当前位置: 首页 > 知识库问答 >
问题:

Elasticsearch通过嵌套查询提高分数

秦毅
2023-03-14

我在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\u短语“java”来给一个人打分,如果它还包含match\u短语“adobe creative suit”,则会额外提高分数,然后检查在“skills”中点击的嵌套值,以查看该技能来自哪种类型的“源”。然后根据嵌套对象的一个或多个源对查询进行增强。

这种方法很有效,至少我没有犯任何错误,但最终的分数很奇怪,很难看出它是否有效。如果我给一个小的提升,比如说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”。在我的新查询中,它们都得到了相同的提升,但这两个文档的最终分数非常不同。

来自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"

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

共有1个答案

蔺劲
2023-03-14

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

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

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

 类似资料:
  • 我试图创建一个嵌套查询,它将过滤掉一些带有特定术语的文档。在本例中,我试图过滤掉在user.first中有匹配术语的文档。数据示例: 我的查询没有得到所需的结果,因为它返回给我所有未筛选的记录。我尝试使用: 我希望这里得到与过滤器不匹配的文档。在这种情况下,它应该只返回第二个文档。做这件事的正确方法是什么?

  • 问题内容: 我正在尝试使用query_string编写查询以检索嵌套对象的数据查询。 我想做的查询的一个例子是: 其中“ a”是嵌套对象,“ id”是“ a”的字段。 我知道我可以使用嵌套查询成功地执行此任务,编写如下查询: 但是,我想避免这种情况。我不想自己弄清楚用户正在搜索嵌套字段并修改查询。我尝试使用“ fields”参数,但它似乎不适用于嵌套对象。 是否可以使用“ query_string

  • 问题内容: 我在获取与Elasticsearch一起使用的嵌套查询时遇到问题(如果我删除了查询字符串之一,则可以使用)。我要解决的问题是我有一个包含关闭列表的文档(关闭)。我想在条件满足另一个值的闭包列表中搜索一个值。那只是从argan = 1的闭包中获得价值 我正在得到这个错误响应; 我的映射如下所示。 有人知道我在做什么错吗? 问题答案: 您的查询不是有效的查询。您需要使用适当的复合查询将其他

  • 我是elasticsearch的新手,对如何进行过滤器、查询和聚合有一些想法,但不确定如何解决下面的问题。我希望能够从下面显示的文档中只查询公司的最新交付(日期和crate_quantity)。我不确定如何去做。有没有办法使用最大聚合从每个文档中只提取最近的交付?

  • 我正在通过jHipster使用Spring Data Elasticsearch支持,并试图更多地了解如何使用搜索来扩展数据库中的一些新关系。 我有了一个新的嵌套关系,它有自己的索引: 我想将结果筛选到特定用户“friend1.id”,并在嵌套文档上搜索匹配的详细信息? 但这似乎没有返回任何结果?

  • 尊敬的弹性搜索专家, 我在查询嵌套对象时遇到问题。允许使用以下简化映射: 并将一些文档放在索引中: 现在我想执行这样的查询: 因此,我想得到匹配的公司与数量匹配的文件。因此,上面的查询应该会告诉我: 以下查询: 应该给我所有公司分配到一个文件,其标题包含“GPU”与匹配的文件数量: 如果表现良好,是否有可能实现这一结果?我显然对匹配的文档不感兴趣,只对匹配文档和嵌套对象的数量感兴趣。 谢谢你的帮助