elasticsearchelasticsearch-nested

Elastic search Query - in array of objects


I have created an Index with 100+ documents, here are the sample 2 documents

Document 1:

"OfficeId": 1, "Officename": "Washers Ltd", "customers": [

{
    "customerid":10,
    "customername": Mike,
    "customerphone": 1111111111
}
,
{
    "customerid":20,
    "customername": Angie,
    "customerphone": 2222222222
} ]

Document 2:

"OfficeId": 2, "Officename": "Coldwell Ltd", "customers": [

{
    "customerid":30,
    "customername": Nathan,
    "customerphone": 1111111111
} ]

From the UI we can search by customername or customerphone. When I am searching by phone 1111111111 I should be getting the 2 documents (hit 0, hit 1) but in the first document/hit 0, how I can filter only to display 1 object?


Solution

  • You need to use nested query along with inner_hits

    Adding a working example with index data, mapping, search query and search result

    Index Mapping:

    {
      "mappings": {
        "properties": {
          "customers": {
            "type": "nested"
          }
        }
      }
    }
    

    Index Data:

    {
      "OfficeId": 2,
      "Officename": "Coldwell Ltd",
      "customers": [
        {
          "customerid": 30,
          "customername": "Nathan",
          "customerphone": 1111111111
        }
      ]
    }
    {
      "OfficeId": 1,
      "Officename": "Washers Ltd",
      "customers": [
        {
          "customerid": 10,
          "customername": "Mike",
          "customerphone": 1111111111
        },
        {
          "customerid": 20,
          "customername": "Angie",
          "customerphone": 2222222222
        }
      ]
    }
    

    Search Query:

    {
      "query": {
        "nested": {
          "path": "customers",
          "query": {
            "bool": {
              "must": [
                {
                  "match": {
                    "customers.customerphone": "1111111111"
                  }
                }
              ]
            }
          },
          "inner_hits": {}
        }
      }
    }
    

    Search Result will be

    "hits": [
          {
            "_index": "67228476",
            "_type": "_doc",
            "_id": "1",
            "_score": 1.0,
            "_source": {
              "OfficeId": 1,
              "Officename": "Washers Ltd",
              "customers": [
                {
                  "customerid": 10,
                  "customername": "Mike",
                  "customerphone": 1111111111
                },
                {
                  "customerid": 20,
                  "customername": "Angie",
                  "customerphone": 2222222222
                }
              ]
            },
            "inner_hits": {
              "customers": {
                "hits": {
                  "total": {
                    "value": 1,
                    "relation": "eq"
                  },
                  "max_score": 1.0,
                  "hits": [
                    {
                      "_index": "67228476",
                      "_type": "_doc",
                      "_id": "1",
                      "_nested": {
                        "field": "customers",
                        "offset": 0
                      },
                      "_score": 1.0,
                      "_source": {
                        "customerid": 10,           // note this
                        "customername": "Mike",
                        "customerphone": 1111111111
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            "_index": "67228476",
            "_type": "_doc",
            "_id": "2",
            "_score": 1.0,
            "_source": {
              "OfficeId": 2,
              "Officename": "Coldwell Ltd",
              "customers": [
                {
                  "customerid": 30,
                  "customername": "Nathan",      
                  "customerphone": 1111111111
                }
              ]
            },
            "inner_hits": {
              "customers": {
                "hits": {
                  "total": {
                    "value": 1,
                    "relation": "eq"
                  },
                  "max_score": 1.0,
                  "hits": [
                    {
                      "_index": "67228476",
                      "_type": "_doc",
                      "_id": "2",
                      "_nested": {
                        "field": "customers",
                        "offset": 0
                      },
                      "_score": 1.0,
                      "_source": {
                        "customerid": 30,       // note this
                        "customername": "Nathan",
                        "customerphone": 1111111111
                      }
                    }
                  ]
                }
              }
            }
          }
        ]
    

    Update 1:

    If you want to include one more match clause, use this query

    {
      "query": {
        "nested": {
          "path": "customers",
          "query": {
            "bool": {
              "must": [
                {
                  "match": {
                    "customers.customerphone": "1111111111"
                  }
                },
                {
                  "match": {
                    "customers.customername": "Nathan"
                  }
                }
              ]
            }
          },
          "inner_hits": {}
        }
      }
    }