ElasticSearch条件字段脚本排序不会排序并吃掉所有结果

yruzcnhs  于 2022-11-02  发布在  ElasticSearch
关注(0)|答案(1)|浏览(233)

我正在使用Java和Spring Data ,Elasticsearch 6.8.14 Api.与Elasticsearch通信。我有返回此类数据的索引(我还包括此搜索结果以显示Map结构)

{
  "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"
          }
        }
      }
    ]
  }
}

因此,基本上有私人和法人在弹性。现在我想得到所有的条目排序的名称。为法人,它将是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中得到任何结果。当我删除排序时,所有结果都被返回。也许脚本一定有问题,但我在log中没有看到任何错误。或者问题是它是嵌套对象?

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(类似于公司名称)的Map是这样的:

"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 "";"
                    + "        }";
        }
b1zrtrql

b1zrtrql1#

对于脚本排序,只能返回类型“数字”,而不能返回“字符串”
您需要在搜索请求中使用runtime mapping

{
  "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"
      }
    }
  ]
}

相关问题