Behavior of + in Simple Query Strings vs. Query Strings

Does the + operator behave differently under simple_query_string queries than under query_string queries?

The simple_query_string documentation says:

  • + signifies AND operation

From my testing and from the way this is worded, it seems like in simple_query_string, the + is effectively replaced with AND. This is different than how the + behaves in query_string queries.

In other words, does this mean that

'simple_query_string': {
    'query': 'book +case'
}

is the same as

'query_string': {
    'query': 'book AND case'
}

but is not the same as

'query_string': {
    'query': 'book +case'
}

?

Boolean clauses in Elasticsearch (and Lucene the underlying library) are applied to single search terms, not pairs. The AND, OR etc operators are for convenience and map to the single search term operators of must, should, not.

So book AND case should actually be better understood as +book +case. Both are "must" clauses. Both are required terms. On the other hand, book +case should be thought of as one should clause (results that match should rank higher) and one must clause (all results should contain this term).

Anyways

  • book AND case == +book +case == MUST(book) MUST(case)
  • book +case == SHOULD(book) MUST(case)

Right, thank you. But I'm seeing that the behavior for simple_query_string queries differ. It seems like the + in book +case on simple_query_string acts like an AND operator, and behaves the same as book AND case (or +book +case) on query_string queries.

You're right, my apologies for not reading thoroughly enough. For what it's worth, I can confirm what you're seeing by running this against query validation endpoint

GET test/_validate/query?explain=true
{
    "query": {
        "simple_query_string": {
           "query": "foo +bar"
        }
    }
}

It does appear both terms are mandatory, I get back the Lucene query "explanation": "+_all:foo +_all:bar"