LoX1904
LoX1904

Reputation: 1

Elasticsearch search for attributes matching query over multiple documents

I have data modeled where multiple documents with different attributes are logically connected over a chainID because the documents are indexed with an undefined amount of time between them i.e. after they're executed in the backend. All documents are indexed on the same index. Example documents:

Doc 1:
   {
     "att1": "a",
     "att2": "b",
     "chainID": "123"
   }
Doc 2:
   {
     "att3": "c",
     "att4": "d",
     "chainID": "123"
   }
Doc 3:
   {
     "att1": "x",
     "att2": "y",
     "chainID": "678"
   }
Doc 4:
   {
     "att3": "z",
     "att4": "u",
     "chainID": "678"
   }

Mapping:

{
    "properties": {
        "att1": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "att2": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "att3": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "att4": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "chainID": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        }
    }
}

I want to group the documents by chainID and search through the aggregated results so that a query with att1=a AND att3=c would have chainID=123 as a result.

I tried the following query which resulted in no matching documents

{
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "att1.keyword": "a"
                    }
                },
                {
                    "term": {
                        "att3.keyword": "c"
                    }
                }
            ]
        }
    },
    "aggs": {
        "chainIDs": {
            "terms": {
                "field": "chainID.keyword"
            },
            "aggs": {
                "docs": {
                    "top_hits": {
                        "_source": [
                            "chainID"
                        ]
                    }
                }
            }
        }
    }
}

It seems like the aggregation happens after the query is processed. What I would like to do is aggregate the documents per their chainID and run the query against the aggregated documents. Is this possible with elasticsearch or do I need to adjust my mappings/data model?

Upvotes: 0

Views: 207

Answers (1)

rabbitbr
rabbitbr

Reputation: 3261

Try replacing "must" with should (logic OR). "Must" requires the same document to have att1=1 and att3=c (logic AND).

{
"query": {
    "bool": {
        "should": [
            {
                "term": {
                    "att1.keyword": "a"
                }
            },
            {
                "term": {
                    "att3.keyword": "c"
                }
            }
        ]
    }
},
"aggs": {
    "chainIDs": {
        "terms": {
            "field": "chainID.keyword"
        },
        "aggs": {
            "docs": {
                "top_hits": {
                    "_source": [
                        "chainID"
                    ]
                }
            }
        }
    }
}

}

Upvotes: 0

Related Questions