How to get only documents that exact match with array of values?


#1

How to get only documents that exact match with array of values?. for ex:
I have a document,

doc 1:
{
"names":["a","b","c"]
}

doc 2:
{
"names":["a","c"]
}

search query:
{
"names":["a","c"]
}
from this query i need only doc2(exactly match) should be returned as a result but I am getting both docs as result. I tried 'terms', must & must_not but no luck. Can anyone guide me how to achieve this?


(Mikhail Khludnev) #2

Index number of elements and use https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-set-query.html


#3

Mikhail, Thanks for your reply. This is was i tried..
PUT lp_data_index
{
"settings": { },
"mappings": {
"composite": {
"properties": {
"required_matches": {
"type": "long"
},
"data": {
"type": "keyword"
}
}
}
}
}

PUT lp_data_index/composite/1
{
"data": [
"cat",
"tiger"
],
"required_matches": 2
}

PUT lp_data_index/composite/2
{
"data": [
"cat"
],
"required_matches": 1
}

So, if search for

GET lp_data_index/composite/_search
{
"query": {
"terms_set": {
"data" : {
"terms" : ["cat"],
"minimum_should_match_field": "required_matches"
}
}
}
}

I'm getting 1 response, this is perfectly fine
"hits": {
"total": 1,
"max_score": 0.2876821,
"hits": [
{
"_index": "lp_data_index",
"_type": "composite",
"_id": "2",
"_score": 0.2876821,
"_source": {
"data": [
"cat"
],
"required_matches": 1
}
}
]
}

But when search for
GET lp_data_index/composite/_search
{
"query": {
"terms_set": {
"data" : {
"terms" : ["cat","tiger"],
"minimum_should_match_field": "required_matches"
}
}
}
}

Im getting both docs, but im expecting only one doc should be in result
"hits": {
"total": 2,
"max_score": 0.5753642,
"hits": [
{
"_index": "lp_data_index",
"_type": "composite",
"_id": "1",
"_score": 0.5753642,
"_source": {
"data": [
"cat",
"tiger"
],
"required_matches": 2
}
},
{
"_index": "lp_data_index",
"_type": "composite",
"_id": "2",
"_score": 0.2876821,
"_source": {
"data": [
"cat"
],
"required_matches": 1
}
}
]
}

So in second case also how to get exactly matching doc?


(Mikhail Khludnev) #4

What does _explain respond?


#5

Sorry couldn't get you,
for this search,

{
"query": {
"terms_set": {
"data": {
"minimum_should_match_field": "required_matches",
"terms": [
"cat",
"tiger"
]
}
}
}
}

for this search I expected only one doc(id:1) in the result, but I'm getting both docs(id:1 & id:2).


(Mikhail Khludnev) #6

Ok. This mm_field works a little contraintuitive. Here we go
$ curl -H 'Content-Type: application/json' http://localhost:9200/lp_data_index/composite/_search?pretty -d '

{

"query": {

"bool":{

 "must": [{

"terms_set": {

"data" : {

"terms" : ["cat","tiger"],

"minimum_should_match_field": "required_matches"

}

}

}], "filter":[{

 "range": { "required_matches": { "gte": "2" }}

}]

}

}

}'

{

"took" : 15,

"timed_out" : false,

"_shards" : {

"total" : 5,

"successful" : 5,

"skipped" : 0,

"failed" : 0

},

"hits" : {

"total" : 1,

"max_score" : 0.5753642,

"hits" : [

  {

    "_index" : "lp_data_index",

    "_type" : "composite",

    "_id" : "1",

    "_score" : 0.5753642,

    "_source" : {

      "data" : [

        "cat",

        "tiger"

      ],

      "required_matches" : 2

    }

  }

]

}

}

Depending on the problem you might replace >= range to exact equality.

Note: in the previous question I mean the way to debug such issues https://www.elastic.co/guide/en/elasticsearch/reference/current/search-explain.html.


#7

Thanks Mikhail.


(system) #8

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.