Home > Software design >  Elastic: Filtering Arrays
Elastic: Filtering Arrays

Time:09-13

Problem

What's the best way to filter for:

  • All records where "type": "red" and "expired": true is present?

Sample structure

[
    {
        "cheeses": [
            {"type": "red", "expired": false},
            {"type": "red", "expired": true},
        ]
    },
    {
       "cheeses": [
            {"type": "yellow", "expired": false},
            {"type": "red", "expired": true},
        ]
    }
]

What I've tried

(just an example of the pattern)

{
    "query": {
        "bool": {
            "filter": [
                {
                    "range": {
                        "cheeses.type": {
                            "gt": "<x>"
                        }
                    }
                },
                {
                    "match": {
                        "cheeses.expired": {
                            "query": true
                        }
                    }
                }
            ]
        }
    }
}

CodePudding user response:

You can use the nested data type, to get only the required matching documents from the array. Adding a working example:

Index Mapping:

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

Search Query:

{
    "query": {
        "nested": {
            "path": "cheeses",
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "cheeses.type": "red"
                            }
                        },
                        {
                            "match": {
                                "cheeses.expired": "true"
                            }
                        }
                    ]
                }
            },
            "inner_hits": {}
        }
    }
}

Search Result:

"hits": [
            {
                "_index": "73615745",
                "_id": "1",
                "_score": 1.0498221,
                "_source": {
                    "cheeses": [
                        {
                            "type": "red",
                            "expired": false
                        },
                        {
                            "type": "red",
                            "expired": true
                        }
                    ]
                },
                "inner_hits": {
                    "cheeses": {
                        "hits": {
                            "total": {
                                "value": 1,
                                "relation": "eq"
                            },
                            "max_score": 1.0498221,
                            "hits": [
                                {
                                    "_index": "73615745",
                                    "_id": "1",
                                    "_nested": {
                                        "field": "cheeses",
                                        "offset": 1
                                    },
                                    "_score": 1.0498221,
                                    "_source": {
                                        "expired": true,
                                        "type": "red"
                                    }
                                }
                            ]
                        }
                    }
                }
            },
            {
                "_index": "73615745",
                "_id": "2",
                "_score": 1.0498221,
                "_source": {
                    "cheeses": [
                        {
                            "type": "yellow",
                            "expired": false
                        },
                        {
                            "type": "red",
                            "expired": true
                        }
                    ]
                },
                "inner_hits": {
                    "cheeses": {
                        "hits": {
                            "total": {
                                "value": 1,
                                "relation": "eq"
                            },
                            "max_score": 1.0498221,
                            "hits": [
                                {
                                    "_index": "73615745",
                                    "_id": "2",
                                    "_nested": {
                                        "field": "cheeses",
                                        "offset": 1
                                    },
                                    "_score": 1.0498221,
                                    "_source": {
                                        "expired": true,
                                        "type": "red"
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
  • Related