我有一个具有以下(简化)结构的文档索引。
{
"product_id": "abc123",
"properties": [
{
"key": "width",
"value": 1000
},
{
"key": "height",
"value": 2000
},
{
"key": "depth",
"value": 500
}
]
}
每个文档可以有数百个属性。
现在 - 我希望能够搜索与查询匹配的文档,还可以指定返回时应填充每个文档的属性。所以基本上我想写下面的请求:
获取与查询x匹配的所有文档,并使用属性[“height”,“width”,“foobar”]填充每个文档。
具有我想要返回的属性的数组是在查询时根据用户的输入创建的。对查询的响应中的文档如下所示:
{
"product_id": "abc123",
"properties": [
{
"key": "width",
"value": 1000
},
{
"key": "height",
"value": 2000
}
// No depth!
]
}
我试图通过源过滤实现这一点无济于事。我怀疑脚本字段可能是解决这个问题的唯一方法,但我宁愿使用一些标准方法。有人有任何想法吗?
我能想到的最好的就是使用inner_hits
。例如:
PUT proptest
{
"mappings": {
"default": {
"properties": {
"product_id": {
"type": "keyword"
},
"color": {
"type": "keyword"
},
"props": {
"type": "nested"
}
}
}
}
}
PUT proptest/default/1
{
"product_id": "abc123",
"color": "red",
"props": [
{
"key": "width",
"value": 1000
},
{
"key": "height",
"value": 2000
},
{
"key": "depth",
"value": 500
}
]
}
PUT proptest/default/2
{
"product_id": "def",
"color": "red",
"props": [
]
}
PUT proptest/default/3
{
"product_id": "ghi",
"color": "blue",
"props": [
{
"key": "width",
"value": 1000
},
{
"key": "height",
"value": 2000
},
{
"key": "depth",
"value": 500
}
]
}
现在我们可以通过color
查询并仅获取height
,depth
和foobar
属性:
GET proptest/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"color": {
"value": "red"
}
}
},
{
"bool": {
"should": [
{
"nested": {
"path": "props",
"query": {
"match": {
"props.key": "height depth foobar"
}
},
"inner_hits": {}
}
},
{
"match_all": {}
}
]
}
}
]
}
},
"_source": {
"excludes": "props"
}
}
输出是
{
"hits": {
"total": 2,
"max_score": 2.2685113,
"hits": [
{
"_index": "proptest",
"_type": "default",
"_id": "1",
"_score": 2.2685113,
"_source": {
"color": "red",
"product_id": "abc123"
},
"inner_hits": {
"props": {
"hits": {
"total": 2,
"max_score": 0.9808292,
"hits": [
{
"_index": "proptest",
"_type": "default",
"_id": "1",
"_nested": {
"field": "props",
"offset": 2
},
"_score": 0.9808292,
"_source": {
"key": "depth",
"value": 500
}
},
{
"_index": "proptest",
"_type": "default",
"_id": "1",
"_nested": {
"field": "props",
"offset": 1
},
"_score": 0.9808292,
"_source": {
"key": "height",
"value": 2000
}
}
]
}
}
}
},
{
"_index": "proptest",
"_type": "default",
"_id": "2",
"_score": 1.287682,
"_source": {
"color": "red",
"product_id": "def"
},
"inner_hits": {
"props": {
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
}
}
]
}
}
请注意,结果包含产品abc123
和def
,并且已过滤了正确的属性。产品abc123
与给定的属性列表部分匹配,def
不包含任何属性列表。主要结果仅由外部查询color:red
定义
该方法的缺点是在相同的顶级_source
下,但在内部命中键下不会找到属性。