Using NOT and OR together in Elastic search - node.js

This the query I used in elastic search to filter records that either satisfy one condition or does not satisfy other condition.
{
"query":
{
"query_string":
{
"query": "(NOT col1: \"val1\") OR (col2: val2)",
"analyze_wildcard": true
}}}
The problem is I am not able to write an equivalent syntax in nodejs to extract the information. We cant use must_not here as it is an OR condition

You will make both conditions in should array, as, if anyone matches you will get the record in results, you will have to use must match and must_not match
{
"query": {
"bool": {
"should": [
{
"bool": {
"must_not": {
"match": {
"col1": {
"query": "val1",
"type": "phrase"
}
}
}
}
},
{
"match": {
"col2": {
"query": "val2",
"type": "phrase"
}
}
}
]
}
}
}

Related

Elasticsearch - Finding all entities with a nested id

I am trying to query a nested item but I am not sure how to formulate the query especially using javascript bodybuilder. Below is the mapping
I am trying to get all the active items (isActive: true) that have the "anomaly" id. I am not sure how to go about querying ElasticSearch.
In SQL I could just do something like a contains or having. I am using Node.js bodybuilder on the backend to query elasticsearch.
according to mapping,isActive and id are related to "anomalies" object. try this query
{
"query": {
"nested": {
"query": {
"bool": {
"filter": [
{
"match": {
"anomalies.isActive": {
"query": "true"
}
}
},
{
"match": {
"anomalies.id": {
"query": "any_value"
}
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
},
"path": "anomalies",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
}
}
}

Elasticsearch keyword + range query (V-6.2)

I am trying to write a query in Elasticsearch to make it work with Range filter and query keyword input from user.
The query that I end up writing is:
"size": val, //default 10,
"from": 0, //default 0,
"query": {
"bool": {
"must": {
"query_string": {
"query": search_query //Val coming from user input
},
"filter": {
"range": {
"lastmodifieddate": {
"gte": '2016-12-09T00:00:00',
"lte": '2016-12-20T00:00:00'
}
}
}
}
}
}
The above query is not working.
Also I am looking for matching 1 of the key value pair from my elasticsearch.
_source:
lastmodifieddate: "2016-12-07T18:34:48.000+0000",
..
..
fileType: "PDF"
...
Can someone throw some light on how to make it work and also a query parameter with all records must match fileType = PDF
TIA
You must put "filter" outside "must". Both of them are in different context. See this documentation https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html
{
"query": {
"bool": {
"must": {
"query_string": {
"query": "user input"
}
},
"filter": {
"range": {
"lastmodifieddate": {
"gte": "2014-01-09T00:00:00",
"lte": "2014-12-20T00:00:00"
}
}
}
}
}
}

Elasticsearch bool query with filter and should

My main aim is to write a query that must search for the searchtext and if any filter of loading port or unloading port is applied then it must filter that from the result of search text.
And if no filter is applied then it should proceed further.
For eg: I search for jeans and if I apply filter then the loading port must be India and its unloading port must be US.
I tried to write this report but it's not giving appropriate result.
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"query_string": {
"query": searchText
}
}
]
}
},
{
"terms": {
"loadingPort":loadingPortArray
}
},
{
"terms": {
"unloadingPort":unloadingPortArray
}
}
]
}
}
}
Your problem is that you are wrapping all the quires\filters inside should, which means that all the statements with be combined by OR logic. If you need AND you need to wrap statements inside must.
By the way, you are not using filter, you are using term query. There is huge difference between query and filter in elasticsearch. To use filter you need to use bool query with filter.
{
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"query_string": {
"query": searchText
}
}
]
}
}
],
"filter": {
"bool": {
"must": [
{
"terms": {
"loadingPort":loadingPortArray
}
},
{
"terms": {
"unloadingPort":loadingPortArray
}
}
]
}
}
}
}
}

ElasticSearch: Show partial match for multi search even if one field does not match

I am currently trying to do a multi search query on first name, last name, and date of birth. I want the results to show a complete match for first, last, and dob but also show results if the first name and last name match but a different date of birth exists then what was queried on.
As of right now my code only returns a result if all three fields have exact matches
GET /account/data/_search
{
"query": {
"match": {
"first": {
"query": "Chris"
}
}
},
"query": {
"match": {
"last": {
"query": "Johnson"
}
}
},
"query": {
"match": {
"dob": {
"query": "10-10-1990"
}
}
}
}
This can be solved with simple bool query
{
"query": {
"bool": {
"must": [
{
"match": {
"first": "TEXT"
}
},
{
"match": {
"last": "TEXT"
}
}
],
"should": [
{
"match": {
"dob": "TEXT"
}
}
]
}
}
}

Elasticsearch lowercase filter search

I'm trying to search my database and be able to use upper/lower case filter terms but I've noticed while query's apply analyzers, I can't figure out how to apply a lowercase analyzer on a filtered search. Here's the query:
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"term": {
"language": "mandarin" // Returns a doc
}
},
{
"term": {
"language": "Italian" // Does NOT return a doc, but will if lowercased
}
}
]
}
}
}
}
}
I have a type languages that I have lowercased using:
"analyzer": {
"lower_keyword": {
"type": "custom",
"tokenizer": "keyword",
"filter": "lowercase"
}
}
and a corresponding mapping:
"mappings": {
"languages": {
"_id": {
"path": "languageID"
},
"properties": {
"languageID": {
"type": "integer"
},
"language": {
"type": "string",
"analyzer": "lower_keyword"
},
"native": {
"type": "string",
"analyzer": "keyword"
},
"meta": {
"type": "nested"
},
"language_suggest": {
"type": "completion"
}
}
}
}
The problem is that you have a field that you have analyzed during index to lowercase it, but you are using a term filter for the query which is not analyzed:
Term Filter
Filters documents that have fields that contain a term (not analyzed).
Similar to term query, except that it acts as a filter.
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html
I'd try using a query filter instead:
Query Filter
Wraps any query to be used as a filter. Can be placed within queries
that accept a filter.
Example:
{
"constantScore" : {
"filter" : {
"query" : {
"query_string" : {
"query" : "this AND that OR thus"
}
}
}
} }
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-filter.html#query-dsl-query-filter
This may be achieved by appending .keyword to your field to query against the keyword version of the field. Assuming language was defined in the mapping with type keyword.
Note that now only the exact text would match: mandarin won't match and Italian would.
Your query would end up like this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"term": {
"language.keyword": "mandarin" // Returns Empty
}
},
{
"term": {
"language.keyword": "Italian" // Returns Italian.
}
}
]
}
}
}
}
}
Combining the term values is also allowed:
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"term": {
"language.keyword":
["mandarin", "Italian"]
}
}
]
}
}
}
}
}

Resources