【问题标题】:ElasticSearch query for getting exact results from Documents用于从文档中获取准确结果的 ElasticSearch 查询
【发布时间】:2019-07-13 15:05:31
【问题描述】:

我有一个索引(名称:“index1”)指向 ElasticSearch 中的多个文档。

文档的格式(json)是 -

{
  "_index": "index1",
  "_type": "someType",
  "_id": "randomIDBlahBlah",
  "_source": {
    "version": "2018",
    "fields": [
      {
        "field": "A.B",
        "lineNumber": 1
      },
      {
        "field": "C.D",
        "lineNumber": 2
      },
      {
        "field": "A.E",
        "lineNumber": 3
      }]
  },
  "fields": {
    "created": [
      "2017-01-19T20:11:07.977Z"
    ]
  },
  "sort": [
    2324343
  ]
}

这是映射 -

{
  "index1": {
    "mappings": {
      "mapping": {
        "properties": {
          "branch": {
            "type": "text"
          },
          "created": {
            "type": "date"
          },
          "fields": {
            "type": "nested",
            "properties": {
              "field": {
                "type": "text"
              },
              "lineNumber": {
                "type": "integer"
              }
            }
          }
        }
      }
    }
  }
}

同样,该索引下有多个文档,格式相同,但字段数据不同。

现在,我正在尝试在特定字段(此处为 A.B)上执行下面提到的弹性搜索,它为我提供所有文档的所有结果,就好像它是对所有字段的搜索一样。

我只想查看特定字段的结果,而不是所有结果。

这是我的 ES 查询 -

POST index1/_search
{
 "query": {
   "bool": {
     "must": [
       {
         "bool": {
           "should": [
             {
               "nested": {
                 "path": "fields",
                 "query": {
                   "match_phrase": {
                     "fields.field": "A.B"
                   }
                 }
               }
             }
           ]
         }
       }
     ]
   }
 }
}

我在 ES 查询中哪里做错了?

【问题讨论】:

  • fields.field 的数据类型是什么?或者,如果您可以将index1 的映射添加到您的问题中,我会更容易理解。
  • fields.field 是字符串类型。我在问题中添加了 index1 的映射。

标签: elasticsearch


【解决方案1】:

如果你的字段不是类型keyword,那么你必须添加类型.keyword

这是由 ES 在 "type": "text" 字段上自动生成的

GET index1/_search
{
 "query": {
   "bool": {
     "must": [
       {
         "bool": {
           "should": [
             {
               "nested": {
                 "path": "fields",
                 "query": {
                   "match_phrase": {
                     "fields.field.keyword: "A.B"
                   }
                 }
               }
             }
           ]
         }
       }
     ]
   }
 }
}```

【讨论】:

  • 您可以在您的问题中发布文档的映射
【解决方案2】:

您使用的查询将为您提供所需的结果。如果您不需要评分,则可以更好地编写如下:

{
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "fields",
            "query": {
              "match": {
                "fields.field": "A.B"
              }
            },
            "inner_hits": {
               "size": 10
            }           
          }
        }
      ]
    }
  },
  "_source": {
     "excludes": [
        "fields"
     ]
  }
}

Inner hits 是您正在寻找的。当有匹配时,弹性返回完整的嵌套对象。如果你只想要匹配的嵌套对象,那么你必须使用inner_hits

更新:如果除了内部点击之外不需要任何字段,则可以设置"_source":false。您也可以根据需要使用includeexcludefilter source

【讨论】:

  • 添加inner_hits后,我仍然看到所有结果。但是,我看到最后的一小部分 inner_hits 具有我想要的确切 1 结果。现在,我怎样才能摆脱一开始出现的所有结果,而只保留最后一个结果?
  • 更新了我的答案。
  • 添加您的建议有效,但不是 100%。字段“C.D”多次出现(在我的情况下为 8 次)但文档中的 lineNumber 不同,这使得每个条目都是唯一的。但是,inner_hits 只显示了几次(在我的情况下 - 仅最后 3 次),而不是全部。我想在我的输出中查看所有出现的字段“C.D”。
  • 此外,当“_source”未设置为 false 时,结果将为我提供“分支”和“创建”属性(请参阅问题中的文档映射)以及结果。但是,在设置 "_source": false 之后,所有这些信息都不再可用。除了“_source”之外,除了“_source”之外,我还想查看所有这些属性。有没有办法做到这一点?
  • 默认情况下内部点击返回前 3 个文档。这可以由inner_hitssize 参数控制。我在答案中添加了指向 inner_hits 文档的链接。有关更多信息,请参阅。
猜你喜欢
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多