0
votes

I've read some articles and documentation about queries/filters in nested objects but I can not make this sample work. Hopefully you can help me to check what is wrong. Bellow is the index and mapping settings I am using:

  # Create Index
  PUT agency

  # Mapping
  PUT agency/site/_mapping
  {
        "site": {
            "properties": {
              "name":{
                "type":"string"
              },
              "phones": {
                 "type": "nested",
                 "properties":{
                   "is_confidential":    { "type": "string"  },
                   "number":    { "type": "string"  },
                   "description": {"type" : "string"}

                 }
              }
           }
        }

  }

  # Indexing one document
  PUT agency/site/1
  {
    "site":{
      "name":"Burger Queen",
      "phones":[
        {
          "is_confidential":"true",
          "number":"10000000000",
          "description":"Manager Phone"
        },
        {
          "is_confidential":"false",
          "number":"10000000001",
          "description":"Public Line"
        },
        {
          "is_confidential":"false",
          "number":"10000000002",
          "description":"Public Line 2"
        },
        {
          "is_confidential":"false",
          "number":"10000000003",
          "description":"Complains Phone"
        }
      ]
    }
  }


  # Query the nested document (https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-query.html)

  GET /agency/site/_search
  {
    "query": {
      "bool": {
        "must": [
          { "match": { "site.name": "Burger" }}, 
          {
            "nested": {
              "path": "phones", 
              "query": {
                "bool": {
                  "must": [ 
                    { "match": { "phones.is_confidential": "false" }}
                  ]
          }}}}
        ]
  }}}


  # Results
  {
    "took": 4,
    "timed_out": false,
    "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
    },
    "hits": {
      "total": 0,
      "max_score": null,
      "hits": []
    }
  }

Why I can not get any results ?

What I am trying to do is filter the parent documents by some term, for example: name = Burger and also filter nested documents to get only those phones where is_confidential = false.

Sample results without any filter applied in nested documents:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "agency",
        "_type": "site",
        "_id": "1",
        "_score": 1,
        "_source": {
          "site": {
            "name": "Burger Queen",
            "phones": [
              {
                "is_confidential": "true",
                "number": "10000000000",
                "description": "Manager Phone"
              },
              {
                "is_confidential": "false",
                "number": "10000000001",
                "description": "Public Line"
              },
              {
                "is_confidential": "false",
                "number": "10000000002",
                "description": "Public Line 2"
              },
              {
                "is_confidential": "false",
                "number": "10000000003",
                "description": "Complains Phone"
              }
            ]
          }
        }
      }
    ]
  }
}

If the site contains several nested objects in the phones array, only those phones that are not confidential should be returned by elasticsearch.

Sample result when is_confidential = false filter is applied:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "agency",
        "_type": "site",
        "_id": "1",
        "_score": 1,
        "_source": {
          "site": {
            "name": "Burger Queen",
            "phones": [
              {
                "is_confidential": "false",
                "number": "10000000001",
                "description": "Public Line"
              },
              {
                "is_confidential": "false",
                "number": "10000000002",
                "description": "Public Line 2"
              },
              {
                "is_confidential": "false",
                "number": "10000000003",
                "description": "Complains Phone"
              }
            ]
          }
        }
      }
    ]
  }
}

Sample result when is_confidential = true:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "agency",
        "_type": "site",
        "_id": "1",
        "_score": 1,
        "_source": {
          "site": {
            "name": "Burger Queen",
            "phones": [
              {
                "is_confidential": "true",
                "number": "10000000000",
                "description": "Manager Phone"
              }
            ]
          }
        }
      }
    ]
  }
}

Is it possible to get those sample results shown above with elasticsearch nested filter (queries)? If is possible could you please show me sample?

1

1 Answers

0
votes

You need to update your PUT clause

Indexing one document

 PUT agency/site/1
  {
    "site":{ // <-- need to remove this as it will alter the mapping definition
      "name":"Burger Queen",
      "phones":[
        {
          "is_confidential":"true",
          "number":"10000000000",
          "description":"Manager Phone"
        },
        {
          "is_confidential":"false",
          "number":"10000000001",
          "description":"Public Line"
        },
        {
          "is_confidential":"false",
          "number":"10000000002",
          "description":"Public Line 2"
        },
        {
          "is_confidential":"false",
          "number":"10000000003",
          "description":"Complains Phone"
        }
      ]
    }
  }

GET agency/site/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "burger"
          }
        },
        {
          "nested": {
            "path": "phones",
            "query": {
              "term": {
                "phones.is_confidential": {
                  "value": "true"
                }
              }
            },
            "inner_hits":{}
          }
        }
      ]
    }
  }
}

The matching nested-documents will be present in the inner hits response.

Sample Response :

{
   "took": 2,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 2.2019112,
      "hits": [
         {
            "_index": "agency",
            "_type": "site",
            "_id": "1",
            "_score": 2.2019112,
            "_source": {
               "name": "Burger Queen",
               "phones": [
                  {
                     "is_confidential": "true",
                     "number": "10000000000",
                     "description": "Manager Phone"
                  },
                  {
                     "is_confidential": "false",
                     "number": "10000000001",
                     "description": "Public Line"
                  },
                  {
                     "is_confidential": "false",
                     "number": "10000000002",
                     "description": "Public Line 2"
                  },
                  {
                     "is_confidential": "false",
                     "number": "10000000003",
                     "description": "Complains Phone"
                  }
               ]
            },
            "inner_hits": {
               "phones": {
                  "hits": {
                     "total": 1,
                     "max_score": 1.9162908,
                     "hits": [
                        {
                           "_index": "agency",
                           "_type": "site",
                           "_id": "1",
                           "_nested": {
                              "field": "phones",
                              "offset": 0
                           },
                           "_score": 1.9162908,
                           "_source": {
                              "is_confidential": "true",
                              "number": "10000000000",
                              "description": "Manager Phone"
                           }
                        }
                     ]
                  }
               }
            }
         }
      ]
   }
}