Mutiple query_strings (nested and not nested) - elasticsearch

I have got the following index:
{
"thread":{
"properties":{
"members":{
"type":"nested",
"properties":{
"memberId":{
"type":"keyword"
},
"firstName":{
"type":"keyword",
"copy_to":[
"members.fullName"
]
},
"fullName":{
"type":"text"
},
"lastName":{
"type":"keyword",
"copy_to":[
"members.fullName"
]
}
}
},
"name":{
"type":"text"
}
}
}
}
I want to implement a search, that finds all threads, that either match the members name or the thread name, as long as the user id matches.
My current query looks like this:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "members",
"score_mode": "none",
"query": {
"bool": {
"filter": [
{ "match": { "members.id": "123456789" } }
]
}
}
}
},
{
"nested": {
"path": "members",
"query": {
"bool": {
"must": {
"simple_query_string": {
"query": "Rhymen",
"fields": ["members.fullName"]
}
}
}
}
}
}
]
}
}
}
Can I filter the members and thread names in one query or do I have to merge two separate queries? I tried adding a "should" with "minimum_should_match: 1" so I could add a second not nested "query_string". But that didn't work as expected (scores were pretty screwed).

yeah i think this should work.
you have to keep the concern for filter memberId in both the filters. Nested filter will need it to match the user with memberId and name.
{
"query": {
"bool": {
"must": [{
"nested": {
"path": "members",
"query": {
"term": {
"members.memberId": {
"value": 1
}
}
}
}
},
{
"bool": {
"should": [{
"term": {
"name": {
"value": "thread_name"
}
}
},
{
"nested": {
"path": "members",
"query": {
"bool": {
"should": [{
"term": {
"members.fullName": {
"value": "trump"
}
}
},
{
"term": {
"members.memberId": {
"value": 1
}
}
}
]
}
}
}
}
]
}
}
]
}
}
}

Related

ElasticSearch should with nested and bool must_not exists

With the following mapping:
"categories": {
"type": "nested",
"properties": {
"category": {
"type": "integer"
},
"score": {
"type": "float"
}
}
},
I want to use the categories field to return documents that either:
have a score above a threshold in a given category, or
do not have the categories field
This is my query:
{
"query": {
"bool": {
"should": [
{
"nested": {
"path": "categories",
"query": {
"bool": {
"must": [
{
"terms": {
"categories.category": [
<id>
]
}
},
{
"range": {
"categories.score": {
"gte": 0.5
}
}
}
]
}
}
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "categories"
}
}
]
}
}
],
"minimum_should_match": 1
}
}
}
It correctly returns documents both with and without the categories field, and orders the results so the ones I want are first, but it doesn't filter the results having score below the 0.5 threshold.
Great question.
That is because categories is not exactly a field from the elasticsearch point of view[a field on which inverted index is created and used for querying/searching] but categories.category and categories.score is.
As a result categories being not found in any document, which is actually true for all the documents, you observe the result what you see.
Modify the query to the below and you'd see your use-case working correctly.
POST <your_index_name>/_search
{
"query": {
"bool": {
"should": [
{
"nested": {
"path": "categories",
"query": {
"bool": {
"must": [
{
"terms": {
"categories.category": [
"100"
]
}
},
{
"range": {
"categories.score": {
"gte": 0.5
}
}
}
]
}
}
}
},
{
"bool": {
"must_not": [ <----- Note this
{
"nested": {
"path": "categories",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "categories.category"
}
},
{
"exists": {
"field": "categories.score"
}
}
]
}
}
}
}
]
}
}
],
"minimum_should_match": 1
}
}
}

Query regarding functionScoreQuery of elastic-builder npm for elasticsearch

I am using a functionScoreQuery provided by the elastic-builder npm to query my elasticsearch, query is getting created but i am not able to get outer query params for my query as shown below.
i.e the outer query params are missing and that is why the query does not execute so i had to manually append query { } in my body. So if anyone can help me out and tell me what i am missing in my npm query to get those query params.
var not_body = elasticbuilder.functionScoreQuery()
.query(elasticbuilder.matchAllQuery())
.functions([
elasticbuilder.weightScoreFunction()
.filter(elasticbuilder.boolQuery().mustNot([
elasticbuilder.hasChildQuery(
elasticbuilder.boolQuery().must([
elasticbuilder.matchPhraseQuery("name", "raju" )
])
).type('student')
]))
.weight(2),
elasticbuilder.weightScoreFunction()
.filter(elasticbuilder.boolQuery().must([
elasticbuilder.hasChildQuery(
elasticbuilder.boolQuery().must([
elasticbuilder.matchPhraseQuery("class", "12")
])
).type('info')
]))
.weight(2)
]).minScore(4).scoreMode('sum');
Current Output body via this query:
{
"function_score": {
"functions": [
{
"filter": {
"bool": {
"must_not": {
"has_child": {
"query": {
"bool": {
"must": {
"match_phrase": {
"name" : "raju"
}
}
}
},
"type": "student"
}
}
}
},
"weight": 2
},
{
"filter": {
"bool": {
"must": {
"has_child": {
"query": {
"bool": {
"must": {
"match_phrase": {
"class" : "12"
}
}
}
},
"type": "info"
}
}
}
},
"weight": 2
}
],
"query": {
"match_all": {}
},
"min_score": 4,
"score_mode": "sum"
}
}
Expected Output body:
{
"query": {
"function_score": {
"functions": [
{
"filter": {
"bool": {
"must_not": {
"has_child": {
"query": {
"bool": {
"must": {
"match_phrase": {
"name" : "raju"
}
}
}
},
"type": "student"
}
}
}
},
"weight": 2
},
{
"filter": {
"bool": {
"must": {
"has_child": {
"query": {
"bool": {
"must": {
"match_phrase": {
"class" : "12"
}
}
}
},
"type": "info"
}
}
}
},
"weight": 2
}
],
"query": {
"match_all": {}
},
"min_score": 4,
"score_mode": "sum"
}
}
}
You should wrap this in a elasticbuilder.requestBodySearch()
In your case
elasticbuilder.requestBodySearch().query(not_body)
should do the job

Filter the records from nested query - Elastic Search

I am having nested array fields, I need to query and filter the records for that.
Sample
"test":{
"name":[
{
"name": "vanaraj",
"Age" : 26
},
{
"name": "vanaraj",
"Age" : 10
},
{
"name": "ranjit",
"Age" : 26
},
]
}
Here how I need the query for below conditions,
1. Where Name is equal to both ["vanaraj","ranjit"] to fetch
2. Add condition where Age > 25 for only "vanaraj"
I need a query like below, but it is not working.
{
"query": {
"bool": {
"filter": [
{
"nested": {
"path": "data.test.name",
"query": {
"bool": {
"filter": [
{
"terms": {
"data.test.name.name": ["vanaraj","ranjit"]
}
}
]
}
}
}
},
{
"nested": {
"path": "data.test.name",
"query": {
"bool": {
"filter": [
{
"term": {
"data.test.name.name": "vanaraj"
}
},
{
"range": {
"data.test.name.Age": {
"gt": 25
}
}
}
]
}
}
}
}
]
}
}
}
Mapping :
{
"mappings":{
"properties":{
"test":{
"properties":{
"name":{
"type":"nested",
"properties":{
"Age":{
"type":"long"
},
"name":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
}
}
}
}
}
}
}
}
Based on your further clarification, the below code should help you:
Solution:
POST <your_index_name>/_search
{
"query": {
"bool": {
"should": [
{
"nested": {
"path": "test.name",
"query": {
"bool": {
"must": [
{
"match": {
"test.name.name": "vanaraj"
}
},
{
"range": {
"test.name.Age": {
"gte": 26
}
}
}
]
}
}
}
},
{
"nested": {
"path": "test.name",
"query": {
"bool": {
"must": [
{
"match": {
"test.name.name": "ranjith"
}
}
]
}
}
}
}
]
}
}
}
The above solution would return you all the documents having name as ranjith OR if name is vanaraj and age > 25
Summary of query:
Bool
- Should
- Must clause for name=vanaraj and age >= 26
- Must clause for name=ranjith
Updated Solution:
POST <your_index_name>/_search
{
"query": {
"bool": {
"should": [
{
"nested": {
"path": "test.name",
"query": {
"bool": {
"must": [
{
"match": {
"test.name.name": "vanaraj"
}
},
{
"range": {
"test.name.Age": {
"gte": 26
}
}
}
]
}
}
}
},
{
"nested": {
"path": "test.name",
"query": {
"bool": {
"must": [
{
"terms": {
"test.name.name": [
"abc",
"ranjit"
]
}
}
]
}
}
}
}
],
"must_not": [
{
"nested": {
"path": "test.name",
"query": {
"bool": {
"must": [
{
"terms": {
"test.name.name": [
"vanaraj"
]
}
},{
"range": {
"test.name.Age": {
"lte": 25
}
}
}
]
}
}
}
}
]
}
}
}
Please run the above and let me know if this helps!

Elasticsearch query error - [or] query malformed, no start_object after query name

Can somebody explain me please what is wrong with this query? I need to convert this generated query from Elasticsearch 2 to Elasticsearch 6. In ES2 this one works well, but in ES6 it throws me an error: [or] query malformed, no start_object after query name. I am lost in it. OR is necessary cause there could be more conditions than this one.
{
"query": {
"bool": {
"filter": {
"or": [
{
"nested": {
"path": "zalozcovia",
"query": {
"bool": {
"filter": [
{
"match": {
"zalozcovia.meno": "\u013dubo\u0161"
}
},
{
"match": {
"zalozcovia.priezvisko": "Majgot"
}
},
{
"match": {
"zalozcovia.mesto": "Trnava"
}
}
]
}
}
}
}
]
}
}
},
"size": 20,
"sort": [
{
"rok": "desc"
},
{
"cislo": "desc"
}
]
}
Thanks.
In ES6 there is afaik no "OR" Query (https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-or-query.html). You should use a bool query and use there the "should" Part (https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-bool-query.html).
{
"query": {
"bool": {
"filter": [{
"bool": {
"should": [{
"nested": {
"path": "zalozcovia",
"query": {
"bool": {
"filter": [{
"match": {
"zalozcovia.meno": "\u013dubo\u0161"
}
},
{
"match": {
"zalozcovia.priezvisko": "Majgot"
}
},
{
"match": {
"zalozcovia.mesto": "Trnava"
}
}
]
}
}
}
}]
}
}]
}
},
"size": 20,
"sort": [{
"rok": "desc"
},
{
"cislo": "desc"
}
]
}
Try changing "filter-or" with should
{
"query": {
"bool": {
"should" : [
{
"nested": {
"path": "zalozcovia",
"query": {
"bool": {
"filter": [
{
"match": {
"zalozcovia.meno": "\u013dubo\u0161"
}
},
{
"match": {
"zalozcovia.priezvisko": "Majgot"
}
},
{
"match": {
"zalozcovia.mesto": "Trnava"
}
}
]
}
}
}
}
]
}
},
"size": 20,
"sort": [
{
"rok": "desc"
},
{
"cislo": "desc"
}
]
}

ElasticSearch ignoring sort when filtered

ElasticSearch Version: 0.90.1, JVM: 1.6.0_51(20.51-b01-457)
I'm trying to do two things with my ElasticSearch query: 1) filter the results based on a boolean (searchable) and "open_date < tomorrow" and 2) two sort by the field "open_date" DESC
This produces the following query:
{
"query": {
"bool": {
"should": [
{
"prefix": {
"name": "foobar"
}
},
{
"query_string": {
"query": "foobar"
}
},
{
"match": {
"name": {
"query": "foobar"
}
}
}
],
"minimum_number_should_match": 1
},
"filtered": {
"filter": {
"and": [
{
"term": {
"searchable": true
}
},
{
"range": {
"open_date": {
"lt": "2013-07-16"
}
}
}
]
}
}
},
"sort": [
{
"open_date": "desc"
}
]
}
However, the results that come back are not being sorted by "open_date". If I remove the filter:
{
"query": {
"bool": {
"should": [
{
"prefix": {
"name": "foobar"
}
},
{
"query_string": {
"query": "foobar"
}
},
{
"match": {
"name": {
"query": "foobar"
}
}
}
],
"minimum_number_should_match": 1
}
},
"sort": [
{
"open_date": "desc"
}
]
}
... the results come back as expected.
Any ideas?
I'm not sure about the Tire code, but the JSON does not correctly construct a filtered query. My guess is that this overflows and causes the sort element to also not be correctly parsed.
A filtered query should be constructed like this (see http://www.elasticsearch.org/guide/reference/query-dsl/filtered-query/ ):
{
"query": {
"filtered": { // Note: this contains both query and filter
"query": {
"bool": {
"should": [
{
"prefix": {
"name": "foobar"
}
},
{
"query_string": {
"query": "foobar"
}
},
{
"match": {
"name": {
"query": "foobar"
}
}
}
],
"minimum_number_should_match": 1
}
},
"filter": {
"and": [
{
"term": {
"searchable": true
}
},
{
"range": {
"open_date": {
"lt": "2013-07-16"
}
}
}
]
}
}
},
"sort": [
{
"open_date": "desc"
}
]
}
Cheers,
Boaz

Resources