2
votes

I am writing one query string to match multiple string in one field.

I need to match documents with type server_physical and has a string field called cpu which will contain words like E5, 2620 and v3.

This is what I got which will exactly return the documents I need:

"_type:server_physical AND *2620* AND *E5* AND *v3*"

But it's not good because it will also match other fields contain these words. When I add the cpu field to the query, no document is matched. Like these:

"_type:server_physical AND cpu:*2620* AND cpu:*E5* AND cpu:*v3*"

or this:

"_type:server_physical AND CPU:(*2620* AND *E5* AND *v3*)"

What is the correct way to do the query string? And I cannot find any additional documentation about query string other than the very short one in elasticsearch official guide which has several sentences about it.

The mapping of this field is:

{
    "index": "not_analyzed",
    "type": "string"
}
1
what is the mapping of field cpu?ChintanShah25

1 Answers

1
votes

Your queries are fine. Both should work:

"_type:server_physical AND cpu:*2620* AND cpu:*E5* AND cpu:*v3*"
"_type:server_physical AND cpu:(*2620* AND *E5* AND *v3*)"

The trick lies in one of the string query parameters lowercase_expanded_terms. It defaults to true and lowercases all the characters that are part of wildcards i.e. your E5 becomes e5. Try setting it to false and all should work:

POST index/_search
{
    "query": {
        "query_string": {
           "query": "_type:server_physical AND cpu:(*2620* AND *E5* AND *v3*)",
           "lowercase_expanded_terms": false
        }
    }
}

Bonus edit: why does it work without cpu:? Because by default query string will then do a search on the _all field (unless you disabled it), which is a concatenation of all your fields in the document. It then gets analyzed and if you don't specify the analyzer the default one will be used which lowercases (among other things) all the terms in the _all field hence it would contain e5 not E5.