在字段

时间:2016-08-25 22:25:25

标签: elasticsearch nest

我们刚刚升级到Elasticsearch 2.3.1(从1.7开始),我们得到了一些我无法解释的奇怪搜索行为。似乎发生的情况是包含bool查询和sort子句的搜索请求正在返回:

  1. 看似不符合给定搜索字词的文档。
  2. 对每个请求的匹配文档的total进行了大不相同的估算
  3. 具有此行为的请求的最小示例:

    post pim_search_1/_search
    {
       "explain": false,
       "track_scores": false,
       "sort": [
          {
             "product_id": {
                "order": "desc"
             }
          }
       ],
       "query": {
          "bool": {
             "filter": [
                {
                   "terms": {
                      "publication": [
                         "public"
                      ]
                   }
                },
                {
                   "query_string": {
                      "query": "iphone",
                      "default_operator": "and"
                   }
                }
             ]
          }
       }
    }
    

    所以在这种情况下," iphone"的查询字符串根本不返回任何iPhone。将explain设置为true会为看似根本没有匹配项的文档产生此结果:

     "_explanation": {
               "value": 0,
               "description": "Failure to meet condition(s) of required/prohibited clause(s)",
               "details": [
                  {
                     "value": 0,
                     "description": "no match on required clause (#ConstantScore(publication:public) #_all:iphone)",
    

    所以该文件没有匹配的条款,但它仍然被退回?

    我们发现了这种行为的两种解决方法:

    1. 排序_score或完全省略sort子句。对其他任何内容进行排序,例如上面的字段或_doc上的字段,会给出不可思议的行为。
    2. 在请求中包含track_scores : true
    3. 所以它似乎与评分和相关性有关。但由于我们在自己的某个领域进行排序,因此我们对相关性或得分不感兴趣。如果没有变通方法,则响应中的max_scorenull,每个文档的_score也是如此。

      这种行为是否可以以任何方式解释,或者我们应该关注群集运行状况/配置/损坏?据该集群称,其健康状况为绿色,该指数的所有分片都显得健康。它目前是一个小型索引,在3个节点上有3个分片(每个分片1个副本)。

      更新

      我进一步调查了这个问题,似乎缓存相关。具体来说,_all字段的fielddata缓存(我不太熟悉Elasticsearch的内部,所以如果不是这样,请纠正我)。

      重现的步骤

      我有一个数据集可以重现问题,发表评论并发送给您。

      使用以下查询:

      post pim_search_1/_search
      {
         "fields": [
             "_all"
         ],
         "explain": true,
         "size": 100,
         "sort": [
            {
               "product_id": {
                  "order": "desc"
               }
            }
         ],
         "query": {
            "bool": {
               "must": [
                  {
                     "query_string": {
                        "default_field": "_all", 
                        "query": "surface",
                        "default_operator": "and"
                     }
                  }
               ],
               "filter": [
                  {
                     "terms": {
                        "publication": [
                           "public"
                        ]
                     }
                  }
               ]
            }  
         }
      }
      
      1. 执行查询。你正在寻找" surface"在这里的查询字符串中,这应该导致总共22次点击。这是对的。多次执行此查询(这似乎对第2步很重要。)
      2. 将查询字符串更改为" iphone"。这将导致22次点击,即使数据集只包含一个应该匹配的项目。 _explanation还提到找到的文档实际上并不匹配,就像上面的例子一样。
      3. 执行此操作:post pim_search_1/_cache/clear
      4. 再次为" iphone"执行查询。它现在应该只返回1次击中,这是正确的。也要多次执行这个。
      5. 再次针对" surface"执行查询,现在只返回1次点击,并再次_explanation表示它未对结果文档进行匹配。
      6. 从查询中删除sort子句,一切正常。包含"track_scores" : true的情况也是如此。
      7. 而不是_cache/clear它也可以重新启动集群。

        我说它与_all字段相关,因为将default_field的{​​{1}}更改为query_string字段(已分析的字段)会导致正确的行为。在这个例子中,我已经primitive_name存储了一个字段(它通常不在我们身边),并且它会在搜索结果中返回,因此您可以对其进行检查(不会这样做)。似乎包含任何奇怪的东西)。

        以上是在Elasticsearch 2.3.5上的单节点集群(我的本地PC)上完成的。

        This Github问题似乎和我的问题差不多,但当时无法复制并被关闭。

1 个答案:

答案 0 :(得分:0)

这已在Elasticsearch 2.4中修复:

https://github.com/elastic/elasticsearch/pull/20196