我有一个具有以下(简化)结构的文档索引。
{
"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!
]
}
我试图通过源过滤来实现这一目标,但无济于事。我怀疑脚本字段可能是解决此问题的唯一方法,但我宁愿使用一些标准方法。任何人有任何想法吗?
答案 0 :(得分:1)
我能想到的最好的方法是使用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
下,而是在内部hits键下找到属性。