22

I have a problem with querying objects in array. Let's create very simple index, add a type with one field and add one document with array of objects (I use sense console):

PUT /test/
PUT /test/test/_mapping
{
    "test": {
        "properties": {
            "parent": {"type": "object"}
        }
    }
}
POST /test/test
{
    "parent": [
        {
            "name": "turkey",
            "label": "Turkey"
        },
        {
            "name": "turkey,mugla-province",
            "label": "Mugla (province)"
        }
    ]
}

Now I want to search by both names "turkey" and "turkey,mugla-province" . The first query works fine:

GET /test/test/_search {"query":{ "term": {"parent.name": "turkey"}}}

But the second one returns nothing:

GET /test/test/_search {"query":{ "term": {"parent.name": "turkey,mugla-province"}}}

I tried a lot of stuff including:

"parent": {
    "type": "nested",
    "include_in_parent": true,
    "properties": {
         "label": {
             "type": "string",
             "index": "not_analyzed"
         },
         "name": {
             "type": "string",
             "store": true
         }
     }
}

But nothing helps. What do I miss?

1
  • Did you want to search for docs matching turkey AND mugla-province, or turkey OR mugla-province? Commented Jun 25, 2015 at 23:20

2 Answers 2

27

Here's one way you can do it, using nested docs:

I defined an index like this:

PUT /test_index
{
   "mappings": {
      "doc": {
         "properties": {
            "parent": {
               "type": "nested",
               "properties": {
                  "label": {
                     "type": "string"
                  },
                  "name": {
                     "type": "string"
                  }
               }
            }
         }
      }
   }
}

Indexed your document:

PUT /test_index/doc/1
{
   "parent": [
      {
         "name": "turkey",
         "label": "Turkey"
      },
      {
         "name": "turkey,mugla-province",
         "label": "Mugla (province)"
      }
   ]
}

Then either of these queries will return it:

POST /test_index/_search
{
    "query": {
        "nested": {
           "path": "parent",
           "query": {
               "match": {
                  "parent.name": "turkey"
               }
           }
        }
    }
}

POST /test_index/_search
{
    "query": {
        "nested": {
           "path": "parent",
           "query": {
               "match": {
                  "parent.name": "turkey,mugla-province"
               }
           }
        }
    }
}

Here's the code I used:

http://sense.qbox.io/gist/6258f8c9ee64878a1835b3e9ea2b54e5cf6b1d9e

Sign up to request clarification or add additional context in comments.

3 Comments

Thx for replay but I need an exact match. Sorry that didn't specified it.
What do you mean by "exact match"? This technique works fine with terms queries/filters too, you just might need "index": "not_analzyed" on on the mapping field. I can update to show that if it will help.
"index": "not_analzyed" - that's what i need! I already pointed other answer as correct, but your suites me better. I will use this solution, thank you for your time!
8

For search multiple terms use the Terms query instead of Term query.

"terms" : {
        "tags" : [ "turkey", "mugla-province" ],
        "minimum_should_match" : 1
    }

There are various ways to construct this query, but this is the simplest and most elegant in the current version of ElasticSearch (1.6)

3 Comments

GET /test/test/_search { "query":{ "terms" : { "parent.name" : ["turkey", "turkey,mugla-province" ] } } } - this one works pretty well! Thx, and I wonder can I somehow point the only one term "turkey,mugla-province" without "turkey"?
You can by simply stating the minimum_should_match : 2, which will only match docs with both. Also you may want to check your analyzer is not breaking on the , or - which is possible and then retry your Term query, or you can use nested docs with different analyzers, there are lots of way to accomplish specific things with ElasticSearch but I'm afraid I don't understand exactly what you are looking for.
"[terms] query does not support [minimum_should_match]", in v7.5 terms the key of each term is the property you want to search for, e.g.: "terms":{"parent.name":[ "turkey", "mugla-province" ]}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.