0

I'm currently quite confuse about the structuring of queries in elastic. Let me explain what I mean with the following template that works fine for me:

{
"template" : {
    "query" : {
        "filtered" : {
            "query" : {
                "bool" : {
                    "must" : [
                        { "match" : {
                            "user"  : "{{param_user}}"
                        } },
                        { "match" : {
                            "session" : "{{param_session}}"
                        } },
                        { "range" : {
                            "date" : {
                                "gte" : "{{param_from}}",
                                "lte" : "{{param_to}}"
                            }
                        } }
                    ]
                }
            }
        }
    }
}
}

Ok so I want to get entries of a specific session of a user in a certain time period. Now if you take a llok at this link http://www.elastic.co/guide/en/elasticsearch/guide/current/combining-filters.html you can find the following query:

{
"query" : {
  "filtered" : { 
     "filter" : {
        "bool" : {
          "should" : [
             { "term" : {"price" : 20}}, 
             { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} 
          ],
          "must_not" : {
             "term" : {"price" : 30} 
          }
       }
     }
  }
}
}

In this example we have right after the "filtered" the "filter" keyword. However if I exchange my second "query" with a "filter" as in the example , my template won't work anymore. This is really counterintuitive and I payed alot of time to figure this out. A̶l̶s̶o̶ ̶I̶ ̶d̶o̶n̶'̶t̶ ̶u̶n̶d̶e̶r̶s̶t̶a̶n̶d̶ ̶w̶h̶y̶ ̶w̶e̶ ̶n̶e̶e̶d̶ ̶t̶o̶ ̶p̶u̶t̶ ̶e̶v̶e̶r̶y̶ ̶f̶i̶l̶t̶e̶r̶ ̶i̶n̶ ̶s̶e̶p̶a̶r̶a̶t̶e̶ ̶̶{̶ ̶}̶̶ ̶e̶v̶e̶n̶ ̶t̶h̶o̶u̶g̶h̶ ̶t̶h̶e̶y̶ ̶a̶r̶e̶ ̶a̶l̶r̶e̶a̶d̶y̶ ̶s̶e̶p̶a̶r̶a̶t̶e̶d̶ ̶b̶y̶ ̶t̶h̶e̶ ̶a̶r̶r̶a̶y̶ ̶s̶y̶n̶t̶a̶x̶.̶

Another issue I had was that I suggested to match several fields I can just type smth like:

{
"query" : {
    "match" : {
        "user"  : "{{param_user}}",
        "session" : "{{param_session}}"
    }
}
}

but it seemed that I have to use a bool query which I didn't know of, so I searched for 'elastic multi match' but got something completely different.

My question: where can I find how to structure a query properly (smth like a PEG)? The documentation only give basic examples but doesn't state what we can actually do and how.

Best regards, Jan

Edit: Ok I just found by accident that I cannot exchange "query" with "filter" as "match" is a query and not a filter. But then again what about "range"? It seems to be a query as well as a filter... Is there a summary of keywords specifying in which context they can be used?

Jan
  • 337
  • 1
  • 2
  • 11

1 Answers1

0

Is there a summary of keywords specifying in which context they can be used?

I wouldn't consider that as keywords. It's just there are both queries and filters with the same names (but not all of them).

Here is everything you need. For example there are both range query and filter. All you need is to understand the difference between filters and queries.

For example, if you want to move range section from query to filter, you can do that like shown in the code below (not tested). Since your code already contains filtered type of query, you can just create filter section right after query section.

{
    "template": {
        "query": {
            "filtered": {
                "query": {
                    "bool": {
                        "must": [
                            {
                                "match": {
                                    "user": "{{param_user}}"
                                }
                            },
                            {
                                "match": {
                                    "session": "{{param_session}}"
                                }
                            }
                        ]
                    }
                },
                "filter": {
                    "range": {
                        "date": {
                            "gte": "{{param_from}}",
                            "lte": "{{param_to}}"
                        }
                    }
                }
            }
        }
    }
}

Just remember that you can filter only not analyzed fields.

Jakub Matczak
  • 15,341
  • 5
  • 46
  • 64
  • Well this makes alot more sense. I didn't understand the difference between filter and query well. Helped me alot but I'm afraid your link is broke ;) – Jan Mar 24 '15 at 14:55
  • Fixed. Just didn't actually copied the link :P Anyway it's just Elasticsearch docs. ;-) You can see the queries and filters available there. Once you'll get the idea of nesting queries/filters, it becomes super easy to use. – Jakub Matczak Mar 24 '15 at 14:59
  • Yes I see. So the idea is to use queries to reduce size of fetched documents (only the relevant) and the filters are then used to narrow them even further depending on what a user want? – Jan Mar 24 '15 at 15:04
  • http://stackoverflow.com/questions/14595988/queries-vs-filters this should help. Also filters can be considered as something similar to casual `WHERE` clause in SQL, while the query is about full text searching. – Jakub Matczak Mar 25 '15 at 08:16