弹性搜索条件字段脚本排序不排序并吃掉所有结果



我使用的是Java和Spring数据,Elasticsearch 6.8.14 Api。与Elasticsearch沟通。我有返回此类数据的索引(我包括此搜索结果以显示映射结构(

{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 6,
"max_score": 1.0,
"hits": [
{
"_index": "people",
"_type": "companyindexeddata",
"_id": "8",
"_score": 1.0,
"_source": {
"id": "8",
"privatePerson": {
"id": "10001",
"name": "Awski"
},
"legalPerson": null
}
},
{
"_index": "people",
"_type": "companyindexeddata",
"_id": "9",
"_score": 1.0,
"_source": {
"id": "9",
"privatePerson": null,
"legalPerson": {
"id": "10001",
"companyName": "Bwski"
}
}
}
]
}
}

所以Elastic基本上有私人和法人。现在我想让所有条目按名称排序。对于法人,它将是companyName字段,而对于简单人,它是name字段。

我正在搜索文档。。

NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageRequest);
SearchQuery searchQuery =  nativeSearchQueryBuilder.withSort(SortBuilders.scriptSort(new Script(getFirstScript()), ScriptSortBuilder.ScriptSortType.STRING).order(SortOrder.ASC));
Page<CompanyIndexedData> results= companyIndexedDataRepository.search(searchQuery);

当我使用这种脚本方法时,我不会从Elastic中得到任何结果。当我删除排序时,所有结果都会返回。也许脚本一定有问题,但我在日志中没有看到任何错误。。或者问题是它是嵌套对象?

nativeSearchQueryBuilder.withSort(SortBuilders.scriptSort(new Script(getFirstScript()), ScriptSortBuilder.ScriptSortType.STRING).order(SortOrder.ASC));

private String getFirstScript() {
return "if (doc.containsKey('privatePerson') && !doc['privatePerson'].empty) {"
+ "            return doc['privatePerson.name'].value;"
+ "        }"
+ "        else if (doc.containsKey('legalPerson') && !doc['legalPerson'].empty) {"
+ "            return doc['legalPerson.companyName'].value;"
+ "        } else {"
+ "           return "";"
+ "        }";
}

由于privatePerson.name(类似于公司名称(映射如下:

"name": {
"type": "text",
"index": false,
"fields": {
"keyword": {
"type": "keyword"
}
}
}

我也尝试过这个脚本,但结果也是空的:

private String getFirstScript() {
return "if (doc.containsKey('privatePerson') && !doc['privatePerson'].empty) {"
+ "            return doc['privatePerson.name.keyword'].value;"
+ "        }"
+ "        else if (doc.containsKey('legalPerson') && !doc['legalPerson'].empty) {"
+ "            return doc['legalPerson.companyName.keyword'].value;"
+ "        } else {"
+ "           return "";"
+ "        }";
}

对于脚本排序,您只能返回类型"数字";而不是";字符串";

您需要在搜索请求中使用运行时映射。

{
"runtime_mappings": {
"sort_name": {
"type": "keyword",
"script": {
"source": """
if(doc["privatePerson.name.keyword"].size()!=0)
emit(doc["privatePerson.name.keyword"].value);
else emit(doc["legalPerson.companyName.keyword"].value);
"""
}
}
},
"sort": [
{
"sort_name": {  --> sort on runtime field
"order": "asc"
}
}
]
}

提高性能。您可以索引运行时字段并直接在查询中使用它

PUT <index-name>/_mapping
{
"runtime": {
"sort_name": {
"type": "keyword",
"script": {
"source": """
if(doc["privatePerson.name.keyword"].size()!=0)
emit(doc["privatePerson.name.keyword"].value);
else emit(doc["legalPerson.companyName.keyword"].value);
"""
}
}
}
}
GET <index-name>/_search
{
"sort": [
{
"sort_name": {
"order": "asc"
}
}
]
}

最新更新