Search code examples
elasticsearchamazon-opensearch

Return parent records even if no child records query matches


(this is actually AWS OpenSearch, which I believe is a fork of Elastic Search 7.x)

So in this contrived example, I have a parent-child relationship between manufacturer and products. I want to return "acme" information and all of the products. Some of the products may be embargoed (not ready to be listed to the public). For a new company, like acme, it only has new embargoed products, so when I run this query, I do not get back the company info. I tried using "min_children": 0, but I still do not get back the manufacturer.

For this query, other manufacturers are returned if they have at least one product that is not embargoed, so it's something about has_child hits not returning any products.

{
    "track_total_hits": true,
    "query": {
        "bool": {
            "must": [
                {
                    "has_child": {
                        "inner_hits": {
                            "name": "manf_products",
                            "size": 100
                        },
                        "min_children": 0,
                        "query": {
                            "bool": {
                                "should": [
                                    {
                                        "range": {
                                            "embargo_date": {
                                                "lt": "now/s"
                                            }
                                        }
                                    }
                                ]
                            }
                        },
                        "type": "product"
                    }
                },
                {
                    "bool": {
                        "should": [
                            {
                                "term": {
                                    "manuf": {
                                        "value": "acme"
                                    }
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

Solution

  • The minimum value of min_children is 1. This can give you more info on this.

    Below query will return parents and child docs which are not embargoed. It will return parent if no child non embargoed child exists

    {
      "track_total_hits": true,
      "query": {
        "bool": {
          "minimum_should_match": 1,
          "should": [
            {
              "has_child": {
                "inner_hits": {
                  "name": "manf_products",
                  "size": 100
                },
                "query": {
                  "bool": {
                    "should": [
                      {
                        "range": {
                          "embargo_date": {
                            "lt": "now/s"
                          }
                        }
                      }
                    ]
                  }
                },
                "type": "product"
              }
            },
            {
              "bool": {
                "must_not": [
                  {
                    "has_child": {
                      "inner_hits": {
                        "name": "manf_products",
                        "size": 100
                      },
                      "query": {
                        "bool": {
                          "should": [
                            {
                              "range": {
                                "embargo_date": {
                                  "lt": "now/s"
                                }
                              }
                            }
                          ]
                        }
                      },
                      "type": "product"
                    }
                  }
                ]
              }
            }
          ],
          "filter": [
            {
              "term": {
                "manf": {
                  "value": "acme"
                }
              }
            }
          ]
        }
      }
    }