【问题标题】:Elasticsearch boost score with nested queryElasticsearch 使用嵌套查询提高分数
【发布时间】:2014-10-08 18:08:17
【问题描述】:

我在 Elasticsearch 1.3.4 版中有以下查询:

{
   "filtered": {
      "query": {
         "bool": {
            "should": [
               {
                  "bool": {
                     "should": [
                        {
                           "match_phrase": {
                              "_all": "java"
                           }
                        },
                        {
                           "bool": {
                              "should": [
                                 {
                                    "match_phrase": {
                                       "_all": "adobe creative suite"
                                    }
                                 }
                              ]
                           }
                        }
                     ]
                  }
               },
               {
                  "bool": {
                     "should": [
                        {
                           "nested": {
                              "path": "skills",
                              "query": {
                                 "bool": {
                                    "must": [
                                       {
                                          "term": {
                                             "skills.name.original": "java"
                                          }
                                       },
                                       {
                                          "bool": {
                                             "should": [
                                                {
                                                   "match": {
                                                      "skills.source": {
                                                         "query": "linkedin",
                                                         "boost": 5
                                                      }
                                                   }
                                                }, 
                                                {
                                                   "match": {
                                                      "skills.source": {
                                                         "query": "meetup",
                                                         "boost": 5
                                                      }
                                                   }
                                                }                                                
                                             ]
                                          }
                                       }
                                    ],
                                    "minimum_should_match": "100%"
                                 }
                              }
                           }
                        }
                     ]
                  }
               }
            ],
            "minimum_should_match": "100%"
         }
      },
      "filter": {
         "and": [
            {
               "bool": {
                  "should": [
                     {
                        "term": {
                           "skills.name.original": "java"
                        }
                     }
                  ]
               }
            },
            {
               "bool": {
                  "should": [
                     {
                        "term": {
                           "skills.name.original": "ajax"
                        }
                     },
                     {
                        "term": {
                           "skills.name.original": "html"
                        }
                     }
                  ]
               }
            }
         ]
      }
   }
}

映射如下所示:

  skills: {
    type: "nested", 
    include_in_parent: true, 
    properties: {                 
      name: {
        type: "multi_field",
        fields: {
          name: {type: "string"},
          original: {type : "string", analyzer : "string_lowercase"} 
        }              
      }                                                       
    }
  }

最后是技能的文档结构(不包括其他部分),如下所示:

  "skills": 
  [
    {
      "name": "java",
      "source": [
         "linkedin", 
         "facebook"
      ]
    },
    {
      "name": "html",
      "source": [
         "meetup"
      ]
    }
  ]

我对这个查询的目标是,首先用过滤器过滤掉一些不相关的命中(查询底部),然后通过在整个文档中搜索 match_phrase “java”来给一个人打分,如果它还包含match_phrase "adobe creative suit",然后检查我们在 "skills" 中命中的嵌套值,以查看该技能来自哪种 "source(s)"。然后根据嵌套对象的来源或来源为查询提供提升。

这种工作,至少我没有得到任何错误,但最终得分是奇怪的,很难看出它是否工作。如果我稍微提升一下,比如说 2,分数会稍微下降,我目前的最高命中分数为 32.176407,提升 = 1。提升 5 时,它会下降到 31.637703。我希望它会上涨,而不是下跌?随着 1000 的提升,分数下降到 2.433376。

这是执行此操作的正确方法,还是有更好/更简单的方法?我可以更改结构和映射等。为什么我的分数会下降?

编辑:我稍微简化了查询,只处理一个“技能”:

{
   "filtered": {
      "query": {
         "bool": {
            "must": [
               {
                  "bool": {
                     "must": [
                        {
                           "bool": {
                              "should": [
                                 {
                                    "match_phrase": {
                                       "_all": "java"
                                    }
                                 }
                              ],
                              "minimum_should_match": 1
                           }
                        }
                     ]
                  }
               }
            ],
            "should": [
               {
                  "nested": {
                     "path": "skills",
                     "score_mode": "avg",
                     "query": {
                        "bool": {
                           "must": [
                              {
                                 "term": {
                                    "skills.name.original": "java"
                                 }
                              }
                           ],
                           "should": [
                              {
                                 "match": {
                                    "skills.source": {
                                       "query": "linkedin",
                                       "boost": 1.2
                                    }
                                 }
                              },
                              {
                                 "match": {
                                    "skills.source": {
                                       "query": "meetup",
                                       "boost": 1.2
                                    }
                                 }
                              }
                           ]
                        }
                     }
                  }
               }
            ]
         }
      },
      "filter": {
         "and": [
            {
               "bool": {
                  "should": [
                     {
                        "term": {
                           "skills.name.original": "java"
                        }
                     }
                  ]
               }
            }
         ]
      }
   }
}

现在的问题是我期望两个相似的文档,唯一的区别是技能“java”的“source”值。它们分别是“linkedin”和“meetup”。在我的新查询中,它们都获得了相同的提升,但两个文档的最终 _score 非常不同。

来自 doc 1 的查询说明:

"value": 3.82485,
"description": "Score based on child doc range from 0 to 125"

对于文档二:

"value": 2.1993546,
"description": "Score based on child doc range from 0 to 125"

这些值是唯一不同的值,我不明白为什么。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我无法回答有关提升的问题,但是您在索引上有多少个分片? TF 和 IDF 是按分片而不是按索引计算的,这可能会造成分数差异。 https://groups.google.com/forum/#!topic/elasticsearch/FK-PYb43zcQ.

    如果您只使用 1 个分片重新索引会改变结果吗?

    编辑:此外,文档范围是分片中每个文档的文档范围,您可以使用它来计算每个文档的 IDF 以验证分数。

    【讨论】:

    • 我不认为这是碎片的问题,也许。我选择了不同的方式,现在使用 function_score 查询来实现其中的一些功能。它是否有效还有待观察。我发现了文档范围,因为我认为它与我的情况无关,我通过在 _all 字段的映射中将 omit_norms 设置为 true 来禁用它。
    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 2018-03-08
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    相关资源
    最近更新 更多