【问题标题】:Elastic termsQuery not giving expected result弹性术语查询未给出预期结果
【发布时间】:2021-03-03 18:05:21
【问题描述】:

我有一个索引,其中我的每个对象都有status 字段,该字段可以有一些预定义的值。我想获取所有这些状态INITIATEDUPDATEDDELETED 的匹配项,因此通过 java 创建了这个查询,我使用 Querybuilder 和 nativeSearchQuery 在控制台上打印,由ElasticsearchOperations 执行:

 {
  "bool" : {
    "must" : [
      {
        "terms" : {
          "status" : [
            "INITIATED",
            "UPDATED",
            "DELETED"
          ],
          "boost" : 1.0
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}

我的索引中有“已启动”状态的数据,但没有找到查询中提到的状态的任何人。请问如何解决这个查询? 如果您需要什么,请告诉我。

更新:添加代码

NativeSearchQueryBuilder nativeSearchQueryBuilder=new NativeSearchQueryBuilder();
QueryBuildersingleQb=QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("status",statusList));
                                        
  Pageable pageable = PageRequest.of(0, 1, Sort.by(Defs.START_TIME).ascending());
                FieldSortBuilder sort = SortBuilders.fieldSort(Defs.START_TIME).order(SortOrder.ASC); 
  nativeSearchQueryBuilder.withQuery(singleQb);
  nativeSearchQueryBuilder.withSort(sort);
  nativeSearchQueryBuilder.withPageable(pageable);
                nativeSearchQueryBuilder.withIndices(Defs.SCHEDULED_MEETING_INDEX);
                nativeSearchQueryBuilder.withTypes(Defs.SCHEDULED_MEETING_INDEX);
    
 NativeSearchQuery searchQuery = nativeSearchQueryBuilder.build();
 List<ScheduledMeetingEntity> scheduledList=elasticsearchTemplate.queryForList(searchQuery, ScheduledMeetingEntity.class);

更新 2:示例数据:

I got this from kibana query on this index:
 "hits" : [
      {
        "_index" : "index_name",
        "_type" : "type_name",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "createTime" : "2021-03-03T13:09:59.198",
          "createTimeInMs" : 1614755399198,
          "createdBy" : "user1@domain.com",
          "editTime" : "2021-03-03T13:09:59.198",
          "editTimeInMs" : 1614755399198,
          "editedBy" : "user1@domain.com",
          "versionId" : 1,
          "id" : "1",
          "meetingId" : "47",
          "userId" : "129",
          "username" : "user1@domain.com",
          "recipient" : [
            "user1@domain.com"
          ],
          "subject" : "subject",
          "body" : "hi there",
          "startTime" : "2021-03-04T07:26:00.000",
          "endTime" : "2021-03-04T07:30:00.000",
          "meetingName" : "name123",
          "meetingPlace" : "placeName",
          "description" : "sfsafsdafsdf",
          "projectName" : "",
          "status" : "INITIATED",
          "failTry" : 0
        }
      }
    ]

【问题讨论】:

  • 您能否粘贴一个文档示例作为您的索引?
  • @SusanMustafa,请立即查看,数据已添加
  • 尝试做一个简单的termsQuery,只用INITIATED,看看有没有结果?尝试在没有分页的情况下进行操作,看看是否有结果?它也可能是您的映射。是关键字类型吗??还是文字??字段状态? stackoverflow.com/questions/53739370/… TermsQuery 需要使用关键字。我建议你不要自己做映射,而是让 ES 为你做。它将创建关键字和其他所有内容(非常聪明)。
  • 我没有映射字段,es 是在程序第一次启动时映射的。因此,根据 es,我猜它们在关键字字段中,因为这是一个单值字段(尽管我没有明确声明为关键字)。我以这种方式为其他人获得了我想要的输出,但这次没有,不知道为什么!您在我的查询中发现任何可疑点吗?
  • 不抱歉。请参阅我的简化建议(1 个查询),不要分页,看看你是否得到结果。否则它的 termsQuery 是错误的,或者你的映射。

标签: java spring-boot elasticsearch


【解决方案1】:

确认您的映射:

GET /yourIndexName/_mapping

看看是否有效

您的映射需要有关键字才能使 TermsQuery 起作用。

{
  "status": {
    "type" "text",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
      }
    }
  }
}

当您第一次推送文档时,ES 可以自动为您进行映射(无需您自己进行)。但是,如果您自己进行映射,您可能会有更好的控制。

无论哪种方式,您都需要为您的状态字段定义关键字。

====================== 替代解决方案:(不区分大小写)

如果您有一个名为 (status) 的字段,并且您要搜索的值是(INITIATED 或 UPDATED,或 DELETED)。

那么你可以这样:

  BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .must(createStringSearchQuery());

public QueryBuilder createStringSearchQuery(){
            QueryStringQueryBuilder queryBuilder = QueryBuilders.queryStringQuery(" INITIATED OR UPDATED OR DELETED ");
            queryBuilder.defaultField("status");

     return queryBuilder;


}

打印 QueryBuilder:

{
    "query_string" : {
      "query" : "INITIATED OR UPDATED OR DELETED",
      "default_field" : "status",
      "fields" : [ ],
      "type" : "best_fields",
      "default_operator" : "or",
      "max_determinized_states" : 10000,
      "enable_position_increments" : true,
      "fuzziness" : "AUTO",
      "fuzzy_prefix_length" : 0,
      "fuzzy_max_expansions" : 50,
      "phrase_slop" : 0,
      "escape" : false,
      "auto_generate_synonyms_phrase_query" : true,
      "fuzzy_transpositions" : true,
      "boost" : 1.0
    }
  }

【讨论】:

  • 感谢您提供替代解决方案。顺便说一句,我的查询问题出在哪里?我只是想知道问题是什么。我已经用我的代码更新了问题,请检查
  • 感谢您明确指出。我知道对于单值字符串,默认情况下它们是关键字,但了解到它们不是。我声明了它们关键字并且它有效。 +1 链接/说明
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
相关资源
最近更新 更多