Elasticsearch多版本文档最新版本字段检索与正确排序方案咨询
Elasticsearch多版本文档最新版本字段检索与正确排序方案咨询
我最近在Elasticsearch里处理多版本的文档数据时碰到了个排序的难题,想请大家帮忙出出主意。
先给大家说明下我的文档结构和数据情况:
原索引Mapping
{ "mappings": { "properties": { "docType": { "type": "keyword" }, "draft": { "type": "object", "properties": { "title": { "type": "keyword" }, ... } }, "release": { "type": "object", "properties": { "title": { "type": "keyword" }, ... } }, ... } } }
示例数据
有两条示例文档:
{ "docType": "text", "draft": { "title": "A" }, "release": { "title": "Zx" } }
{ "docType": "folder", "draft": { "title": "B" }, "release": { "title": "Yx" } }
需求说明
我想要实现的是:获取文档最新版本的字段(实际不止标题,这里以标题为例)。最新版本的规则是:优先取draft版本的内容,但如果draft不符合过滤条件,就返回release版本的内容。
举个例子:
- 无任何过滤条件时,应该返回draft的标题:
A、B - 过滤标题包含
x的文档时,因为draft的标题都不含x,所以返回release的标题:Zx、Yx
当前实现的问题
我写了一个查询语句,能满足检索的需求,但排序逻辑出了问题:
{ "query" : { "bool" : { "should" : [ { "bool" : { "must" : [ { "simple_query_string" : { "fields" : [ "release.title" ], "query" : "*x*", "default_operator" : "AND", "analyze_wildcard" : true, "_name": "release" } } ] } }, { "bool" : { "must" : [ { "simple_query_string" : { "fields" : [ "draft.title" ], "query" : "*x*", "default_operator" : "AND", "analyze_wildcard" : true, "_name": "draft" } } ] } } ], "minimum_should_match" : 1 } }, "from" : 0, "size" : 40, "sort" : [ { "draft.title" : { "order" : "asc" } }, { "release.title" : { "order" : "asc" } } ], "fields" : [ "draft.title", "release.title" ], "source_filtering" : "false" }
比如在过滤标题含x的场景下,我期望排序后的结果是Yx、Zx(按release.title升序),但实际返回的是Zx、Yx——因为当前排序是先按draft.title升序(也就是A、B的顺序),对应的文档release标题就是Zx、Yx,完全不符合我要按实际返回的release标题排序的需求。
我尝试过的方案(但没解决)
后来我把文档结构改成了嵌套对象的形式,把draft和release都放到workspace嵌套对象里,新增workspace.name来标记是draft还是release:
{ "mappings": { "properties": { "docType": { "type": "keyword" }, "workspace": { "type": "nested", "properties": { "name": { "type": "keyword" }, "title": { "type": "keyword" }, ... } }, ... } } }
然后尝试用嵌套排序:
... "sort": [ { "workspace.title": { "nested": { "path":"workspace", "max_children": 2 }, "order": "asc" } } ], ...
但这也不行——它会把所有workspace里的title都纳入排序考量,哪怕有些版本并不匹配过滤条件;就算把max_children设为1,我也没法控制它优先取draft还是取匹配过滤条件的那个版本来排序。
想请教的问题
有没有办法实现这样的排序逻辑:根据文档实际命中的版本(draft或release),用对应版本的字段来排序?比如:
- 如果文档命中了draft的过滤条件,就用
draft.title排序; - 如果文档只命中了release的过滤条件,就用
release.title排序;
或者换个思路,有没有办法让排序优先使用draft的字段,当draft不命中过滤条件时,自动切换为用release的字段排序?
谢谢大家的帮忙!
内容来源于stack exchange
相关产品推荐
相关产品推荐

