【问题标题】:must_not is not giving expected result in Elasticsearch for empty fieldmust_not 未在 Elasticsearch 中为空字段提供预期结果
【发布时间】:2021-11-27 08:36:22
【问题描述】:

这是我的示例 es 索引文档:

"hits" : [
   {
    "_index" : "project_note",
    "_type" : "project_note",
    "_id" : "19",
    "_score" : 1.0,
    "_source" : {
      "createTime" : "2021-10-04T13:43:55.330",
      "createTimeInMs" : 1633333435330,
      "createdBy" : "test",
      "editTime" : "2021-10-04T13:43:55.330",
      "editTimeInMs" : 1633333435330,
      "editedBy" : "test",
      "versionId" : 1,
      "id" : "19",
      "organizationId" : "28",
      "accessLevel" : "PUBLIC",
      "status" : "ACTIVE",
      "projectId" : "95",
      "userId" : 129,
      "noteType" : "SYSTEM_GENERATED",
      "projectDemographicLogId" : "1"
    },
   {
    "_index" : "project_note",
    "_type" : "project_note",
    "_id" : "19",
    "_score" : 1.0,
    "_source" : {
      "createTime" : "2021-10-04T13:43:55.330",
      "createTimeInMs" : 1633333435330,
      "createdBy" : "test",
      "editTime" : "2021-10-04T13:43:55.330",
      "editTimeInMs" : 1633333435330,
      "editedBy" : "test",
      "versionId" : 1,
      "id" : "19",
      "organizationId" : "28",
      "accessLevel" : "PUBLIC",
      "status" : "ACTIVE",
      "projectId" : "95",
      "userId" : 129
     
    }
]

在第一个文档中,它有 noteType,但在第二个文档中,我没有将该字段存储在 db 中。 我想排除 noteType==null 或 noteType 不存在的文档。 但是,我只得到具有 noteType="SYSTEM_GENERATED"

的文档

我的做法:

{
  "query":
  {
  "bool" : {
    "must" : [
      {
        "term" : {
          "projectId" : {
            "value" : "95",
            "boost" : 1.0
          }
        }
      },
      {
        "range" : {
          "createTimeInMs" : {
            "from" : null,
            "to" : 1633594455000,
            "include_lower" : true,
            "include_upper" : true,
            "boost" : 1.0
          }
        }
      }
    ],
    "must_not" : [
      {
        "term" : {
          "noteType" : {
            "value" : "SYSTEM_GENERATED",
            "boost" : 1.0
          }
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}
  
}

等效的java代码:

  BoolQueryBuilder queryBuilder= QueryBuilders.boolQuery();
               queryBuilder.must(QueryBuilders.termQuery("projectId", requestInfo.getProjectId()));
               queryBuilder.must(rangeQuery("createTimeInMs").lte(requestInfo.getCreateTimeInMs()));

               if(!requestInfo.isIncludeLog()) {
                 
                   queryBuilder.mustNot(QueryBuilders.termQuery("noteType", Defs.SYSTEM_NOTE_TYPE));
                 
               }

【问题讨论】:

  • 基于以上示例索引数据,您期望的搜索结果是什么?
  • 我在 java 代码部分中纠正了一行。我想排除具有 noteType='system-generated' 值的文档
  • 表示您的预期搜索结果是第二个文档?
  • 是的,我只想获取第二个文档
  • 请注意,这两个文档都没有projectId: 96 并且根本没有projectId 字段

标签: java spring-boot elasticsearch


【解决方案1】:

如果只使用查询的must_not 部分(不包括must 部分)

{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "noteType.keyword": {
              "value": "SYSTEM_GENERATED",
              "boost": 1.0
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1.0
    }
  }
}

搜索结果与您期望得到的结果相似

"hits": [
      {
        "_index": "69477995",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.0,
        "_source": {
          "createTime": "2021-09-26T15:54:08.373",
          "createTimeInMs": 1632650048373,
          "createdBy": "test",
          "editTime": "2021-09-26T15:54:08.373",
          "editTimeInMs": 1632650048373,
          "editedBy": "test",
          "versionId": 1,
          "id": "18",
          "note": "note-1, simple note ",
          "organizationId": "28",
          "accessLevel": "PUBLIC",
          "status": "ACTIVE",
          "taskId": "5",
          "userId": 129
        }
      }
    ]

【讨论】:

  • @user404 你能分享你的noteType字段的索引映射吗?
  • 我无意中复制了一个稍微错误的数据,但结构和想法是相同的[更新了文档]。在这里,我需要通过在我的 java 代码中添加的projected 和createTimeInMs 来搜索它们。
  • noteType 只是一个plan String,没有使用关键字
  • yes @user404 但术语查询适用于 keyword 类型字段。在您的映射中,您可能已将 noteType 字段定义为 text 类型。您是否明确声明了索引映射,或者您使用的是默认映射?
  • 我使用的是默认的。没有为 noteType 指定键。简单定义:private String noteType;
猜你喜欢
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 2018-05-19
  • 1970-01-01
  • 2016-03-31
  • 2020-10-10
相关资源
最近更新 更多