Elastic search Query - in array of objects

1k views Asked by At

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?

1

There are 1 answers

11
ESCoder On BEST ANSWER

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": {}
    }
  }
}