Creating an Elastic Search AND OR Query - elasticsearch

I am trying to write a query that requires "area" to be 530 and "starts" to be 06192013 OR "area" to be "530" and "starts" to be "blank". Additionally, in both of those scenarios "space" to be "top" OR "space2" to be "bottom". This query seems to be grabbing anything that matches any of these scenarios, how do I change it to make it work like I would like?
{
"size":25,
"from":0,
"query": {
"custom_filters_score": {
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{"term":{"type":"ghost"}},
{"term":{"area":"530"}}
]
}
},
"filter" : {
"or": [
{"terms":{"space": ["top"]}},
{"terms":{"space2":["bottom"]}},
{
"and": [
{"term":{"area":"530"}},
{"term":{"start":"06192013"}}
]
},
{
"and": [
{"term":{"area":"530"}},
{"term":{"starts":"blank"}}
]
}
]
}
}
},
"filters": [
{"filter":{"term":{"filter1":5743}}, "boost":"1000"},
{"filter":{"term":{"filter2":4451}}, "boost":"64"},
{"filter":{"term":{"filter3":["tech"]}}, "boost":"16"},
{"filter":{"terms":{"filter4":[]}}, "boost":"8"},
{"filter":{"terms":{"filter5":[]}}, "boost":"5"},
{"filter":{"term":{"access":"1"}}, "boost":"2"}
],
"score_mode":"total"
}
}
}

You are almost there! Try this:
...
"query" : { "match_all":{} },
"filter" : {
"and": [
{
"or": [
{"term":{"space": "top"}},
{"term":{"space2":"bottom"}}
]
},
{
"and": [
{"term":{"area":"530"}},
{
"or": [
{"term":{"start":"06192013"}},
{"term":{"starts":"blank"}}
]
}
]
}
]
}
...
Unless you need scoring (which it doesnt look like) you should do all of this with filters, they don't calculate scores and are faster because of this.
The "query" : { "match_all":{} } will end up giving all docs witch match the filter the same score.
Note: I also turned your terms query with an array of one element to a term query...

Related

ElasticSearch multimatch substring search

I have to combine two filters to match requirements:
- a specific list of values in r.status field
- one of the multiple text fields contains the value.
Result query (with using Nest, but it doesn't matter) looks like:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"isActive": {
"value": true
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"terms": {
"r.status": [
"VALUE_1",
"VALUE_2",
"VALUE_3"
]
}
},
{
"bool": {
"should": [
{
"match": {
"r.g.firstName": {
"type": "phrase",
"query": "SUBSTRING_VALUE"
}
}
},
{
"match": {
"r.g.lastName": {
"type": "phrase",
"query": "SUBSTRING_VALUE"
}
}
}
]
}
}
]
}
},
"path": "r"
}
}
]
}
}
]
}
}
}
Also tried with multi_match query:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"isActive": {
"value": true
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"terms": {
"r.status": [
"VALUE_1",
"VALUE_2",
"VALUE_3"
]
}
},
{
"multi_match": {
"query": "SUBSTRING_VALUE",
"fields": [
"r.g.firstName",
"r.g.lastName"
]
}
}
]
}
},
"path": "r"
}
}
]
}
}
]
}
}
}
FirstName and LastName are configured in index mappings as text:
"firstName": {
"type": "text"
},
"lastName": {
"type": "text"
}
Elastic gives a lot of full-text search options: multi_match, phrase, wildcards etc. But all of them fail in my case looking a sub-string in my text fields. (terms query and isActive one work well, I just tried to run only them).
What options do I have also or maybe where I made a mistake?
UPD: Combined wildcards worked for me, but such query looks ugly. Looking for a more elegant solution.
The elasticsearch way is to use ngram tokenizer.
The ngram analyzer will split your terms with a sliding window. For example, the input "Hello World" will generate the following terms:
Hel
Hell
Hello
ell
ello
...
Wor
World
orl
...
You can configure the minimum and maximum size of the sliding window (in the example the minimum size is 3). Once the sub terms are generated you can use a match query an the subfield.
Another point, it is weird to use must within a filter. If you are interested in the score, you should always use must otherwise use filter. Read this article for a good understanding.

ElasticSearch - Single match to multiple

Note that I am a complete newbie with ElasticSearch and I'm on a time crunch. I've got the query below:
{
    "query": {
        "filtered": {
            "query": {
                "match": {
                    "state": "VA"
                }
            },
            "filter": {
                "and": [
                    {
                        "bool": {
                            "must": [
                                {
                                    "match": {
                                        "status": "Active"
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
    },
    "sort": [
        "dom"
    ],
    "size": 1
}
At the moment, the codebase only supports searching for items with one state in particular. I am trying to modify it to support a list of possible state values. Now, I've seen where one can use should and terms but the results for both are empty data sets.
I've tried looking this up but examples I've seen either don't work, or have very poorly explained (if at all) solutions, or depend on reading and absorbing pages of documentation (for which I simply do not have the time). How would I modify the top query to search for multiple values?
Update
Running the following:
curl -XGET localhost:9200/listings/_mapping/listing/field/state?pretty
I have acquired this mapping:
{
"listings" : {
"mappings" : {
"listing" : {
"state" : {
"full_name" : "state",
"mapping" : {
"state" : {
"type" : "string"
}
}
}
}
}
}
}
Update 2
I've updated the mapping to set it to not_analyzed and enabled the store option. Data has been reimported. The new request looks like this:
{
"query":{
"filtered":{
"filter":{
"and":[
{
"bool":{
"should":[
{
"terms":{
"state":["VA","MD"]
}
}
]
}
},{
"bool":{
"must":[
{
"match":{
"status":"Active"
}
}
]
}
}
]
}
}
},
"sort":["dom"],
"size":1
}
Did you try replacing the inner "query" for your "reverse engineered" query?
Something like this:
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"match": {
"state": "VA"
}
},
{
"match": {
"state": "MD"
}
}
]
}
},
"filter": {
"and": [
{
"bool": {
"must": [
{
"match": {
"status": "Active"
}
}
]
}
}
]
}
}
},
"sort": [
"dom"
],
"size": 1
}
By the way, this query is a bit messy. You could reestrucuture it combining the "must" and "should" clauses under a single "bool". You could then discard the "filtered" query and use the single "bool" immediately under root "query" tag, or discard "query" section of "filtered" and use only the "filter" part.

Can we use multiple terms condition in elasticsearch filters

Is it possible to use multiple terms condition for specific fields in bool filter?
query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"terms": {
"events": [
"abc",
"def",
"ghi",
"jkl"
]
},
"terms" : {
"users" : [
"user_1",
"user_2",
"user_3"
]
}
}
]
}
}
}
}
First terms filter is working fine, but i am not able to use second terms, Please correct if i am doing anything wrong with the above query.
You were almost there, you forgot one brace. Here's correct query:
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"terms": {
"events": [
"abc",
"def",
"ghi",
"jkl"
]
}
},
{
"terms": {
"users": [
"user_1",
"user_2",
"user_3"
]
}
}
]
}
}
}
}
}
This will evaluate both conditions:
Your event must be one of abc/def/ghi/jkl
User must be either user_1/user_2/user_3
Basicly each terms query/filter needs to be wrapped up in its' own braces and they need to be siblings.

How to make a RESTful query to the elasticsearch search API for logs within a certain #timestamp range.

I am trying to query elasticsearch for all logs that have a #timestamp within a certain range. This is being done by a $.get() request using jQuery. My attempts so far have resulted in queries not within the time range. I am listing the logs on my own HTML page and although I have tried different query messages I always get one of two responses, one with times starting at 4:25 and the other with times starting at 6:39. I don't know if this is useless information but I thought it could be useful in understanding the nature of the problem.
So this is the message I have written myself.
{
"query" : {
"filtered": {
"query" : { "match_all" : {}},
"filter": {
"range" : {
"#timestamp": {
"from" : 1393580102248,
"to" : 1393583702248
}
}
}
}
}
}
We are also using Kibana (working) and I have tried copying and pasting the same exact query Kibana uses, with the SAME results as my query above.
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "*"
}
}
]
}
},
"filter": {
"bool": {
"must": [
{
"match_all": {}
},
{
"range": {
"#timestamp": {
"from": 1393580102248,
"to": 1393583702248
}
}
},
{
"bool": {
"must": [
{
"match_all": {}
}
]
}
}
]
}
}
}
},
"highlight": {
"fields": {},
"fragment_size": 2147483647,
"pre_tags": [
"#start-highlight#"
],
"post_tags": [
"#end-highlight#"
]
},
"size": 500,
"sort": [
{
"#timestamp": {
"order": "desc"
}
}
]
}
What am I doing wrong? I can change the time range as well and I still get the same results.

Elastic Search: No query registered for [or]

Can anyone help me with this query? I am getting an error returned: "No query registered for [or]" Did I structure this wrong? It's supposed to filter all results where area is 530 and start is blank OR area is 530 and start is "06192013", then based on that boost the document with the other filters.
{
"query": {
"custom_filters_score": {
"query": {
"bool": {
"must": [
{"field":{"sector":"sector1"}},
{"term":{"user_type":"ghost"}},
{"term":{"area":"530"}}
]
},
"filter":{
"or": [
{
"and": [
{"term":{"area":"530"}},
{"term":{"start":"06192013"}}
]
},
{
"and": [
{"term":{"area":"530"}},
{"term":{"start":"blank"}}
]
}
]
}
},
"filters": [
{"filter":{"term":{"relevance" :5726}},"boost":"1000"},
{"filter":{"term":{"relevance2":5726}},"boost":"100"}
],
"score_mode":"total"
}
}
}
The filter object that contains the or filter is misplaced. I guess you wanted to use a filtered query containing the bool query and the or filter like this:
{
"filtered" : {
"bool": {
"must": [
{"field":{"sector":"sector1"}},
{"term":{"user_type":"ghost"}},
{"term":{"area":"530"}}
]
},
"filter" : {
"or": [
{
"and": [
{"term":{"area":"530"}},
{"term":{"start":"06192013"}}
]
},
{
"and": [
{"term":{"area":"530"}},
{"term":{"start":"blank"}}
]
}
]
}
}
}

Resources