我使用的是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"
}
}
]
}