elasticsearch elasticsearch中具有多个相同嵌套类型项的嵌套筛选
我是elasticsearch的新手,所以我的方法可能是完全错误的,但我想建立一个食谱索引,允许用户使用仍然在子集中找到的聚合成分对其进行过滤 也许我用了错误的语言来解释,所以这个例子可能会澄清。我想搜索带有elasticsearch elasticsearch中具有多个相同嵌套类型项的嵌套筛选,elasticsearch,filter,nested,aggregation,elasticsearch,Filter,Nested,Aggregation,我是elasticsearch的新手,所以我的方法可能是完全错误的,但我想建立一个食谱索引,允许用户使用仍然在子集中找到的聚合成分对其进行过滤 也许我用了错误的语言来解释,所以这个例子可能会澄清。我想搜索带有盐一词的食谱;这就产生了三种配方: 配料:盐、面粉、水 配料:盐、胡椒、鸡蛋 配料:水、面粉、鸡蛋、盐 结果配料上的骨料返回盐、面粉、水、胡椒、鸡蛋。当我使用面粉过滤时我只希望配方1和配方3出现在搜索结果中(并且配料上的聚合应该只返回盐、面粉、水、鸡蛋和盐)。当我添加另一个过滤器egg时,我
盐一词的食谱;这就产生了三种配方:
配料:盐、面粉、水
配料:盐、胡椒、鸡蛋
配料:水、面粉、鸡蛋、盐
结果配料上的骨料返回盐、面粉、水、胡椒、鸡蛋。当我使用面粉过滤时
我只希望配方1和配方3出现在搜索结果中(并且配料上的聚合应该只返回盐、面粉、水、鸡蛋和盐)。当我添加另一个过滤器egg
时,我只希望出现配方3(骨料应只返回水、面粉、鸡蛋和盐)
我无法使后者起作用:默认查询旁边的一个过滤器会根据需要缩小结果的范围,但当将其他术语(egg)添加到术语过滤器时,结果也开始包括b,就像它是一个或过滤器一样。但是,将和
添加到筛选器执行不会导致任何结果。。。我做错了什么
我的映射:
{
"recipe": {
"properties": {
"title": {
"analyzer": "dutch",
"type": "string"
},
"ingredients": {
"type": "nested",
"properties": {
"name": {
"type": "string",
"analyzer": "dutch",
"include_in_parent": true,
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
}
我的问题是:
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"match": {
"_all": "salt"
}
}
]
}
},
"filter": {
"nested": {
"path": "ingredients",
"filter": {
"terms": {
"ingredients.name": [
"flour",
"egg"
],
"execution": "and"
}
}
}
}
}
},
"size": 50,
"aggregations": {
"ingredients": {
"nested": {
"path": "ingredients"
},
"aggregations": {
"count": {
"terms": {
"field": "ingredients.name.raw"
}
}
}
}
}
}
为什么在这里使用嵌套的
映射?它的主要目的是保持子对象属性之间的关系,但是成分
字段只有一个属性,可以简单地建模为字符串字段
因此,如果您像这样更新映射:
POST recipes
{
"mappings": {
"recipe": {
"properties": {
"title": {
"type": "string"
},
"ingredients": {
"name": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
}
}
您仍然可以将您的食谱索引为:
{
"title":"recipe b",
"ingredients":["salt","pepper","egg"]
}
此查询将提供您正在等待的结果:
POST recipes/recipe/_search
{
"query": {
"filtered": {
"query": {
"match": {
"_all": "salt"
}
},
"filter": {
"terms": {
"ingredients": [
"flour",
"egg"
],
"execution": "and"
}
}
}
},
"size": 50,
"aggregations": {
"ingredients": {
"terms": {
"field": "ingredients"
}
}
}
}
即:
{
...
"hits": {
"total": 1,
"max_score": 0.22295055,
"hits": [
{
"_index": "recipes",
"_type": "recipe",
"_id": "PP195TTsSOy-5OweArNsvA",
"_score": 0.22295055,
"_source": {
"title": "recipe c",
"ingredients": [
"salt",
"flour",
"egg",
"water"
]
}
}
]
},
"aggregations": {
"ingredients": {
"buckets": [
{
"key": "egg",
"doc_count": 1
},
{
"key": "flour",
"doc_count": 1
},
{
"key": "salt",
"doc_count": 1
},
{
"key": "water",
"doc_count": 1
}
]
}
}
}
希望这能有所帮助。我正朝着这个方向前进,但你给出了完整的答案(实际上我在嵌套对象旁边添加了一个字符串数组,但正如你所说的,这有点过于工程化了)。谢谢非常简单:)谢谢还不够:非常感谢你给出了这个广泛的答案!不客气:)嵌套对象的问题是,您的术语
筛选条件在成分
子对象上进行筛选,该子对象将在同一子对象中同时包含鸡蛋
和面粉
。是的,我也意识到了这一点。。。但我也曾尝试过嵌套布尔过滤器(即使是查询每个成分“术语”的嵌套集的过滤器),无论如何,有时候解决方案只是简化一些东西:)