Elasticsearch 2.X,查询标签,并按标签权重排序结果



我使用的是elasticsearch 2.3

我有一个图书索引。每本书都有标签,每个标签都有重量。我想获得所有有请求标签的书,按标签权重排序。 例如:

PUT book/book/0
{
    "name": "book 0",
    "tags": [
        {"t": "comedy", "w": 30},
        {"t": "drama","w": 20},
    ]
}
PUT book/book/1
{
    "name": "book 1",
    "tags": [
        {"t": "comedy", "w": 10},
        {"t": "drama","w": 5},
        {"t": "other","w": 50},
    ]
}
PUT book/book/2
    {
        "name": "book 2",
        "tags": [
            {"t": "comedy", "w": 5},
            {"t": "drama","w": 30},
        ]
    }
PUT book/book/3
    {
        "name": "book 3",
        "tags": [
            {"t": "comedy", "w": 5},
            {"t": "other","w": 30},
        ]
    }

我要搜索所有带有喜剧和戏剧标签的书。结果顺序为:

  1. book 0 (20+30)
  2. 第二册(30+5)
  3. 第1册(10+5)

更新:我想只返回与两个标签都匹配的图书(并且只按请求的标签排序)。因此,如果我搜索"戏剧"one_answers"喜剧",只会返回具有这两个标签的书籍(在本例中是book 0, book 1, book2),并按请求的标签权重排序。

我怎样才能得到这个?有查询的例子吗?

Ibrahim的答案是正确的,如果你总是想要求和所有的权重,即使标签不匹配你的查询。

如果您只想考虑正在搜索的标签的权重,则必须将tags索引为nested对象。这是因为否则所有的t s和w s都被平铺成列表,在过程中失去了关联(在这里描述)。

然后,您可以使用function_score查询包装在nested查询中,仅对匹配标记的权重求和。你必须启用脚本。

下面是一个例子:

GET /book/_search
{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "function_score": {
          "query": {
            "bool": {
              "filter": [
                {
                  "terms": {
                    "tags.t": [
                      "comedy",
                      "drama"
                    ]
                  }
                }
              ]
            }
          },
          "functions": [
            {
              "script_score": {
                "script": "return doc['tags.w'].value"
              }
            }
          ],
          "boost_mode": "replace"
        }
      },
      "score_mode": "sum"
    }
  }
}


= = =编辑@Eyal Ch评论后= = =

如果只返回匹配两个标签的图书(在示例中是喜剧和戏剧),则会变得更复杂,因为每个搜索词都需要自己的nested查询。

下面是一个例子:

GET /book/_search
{
  "query": {
    "bool": {
      "must":
      [
        {
          "nested": {
            "path": "tags",
            "query": {
              "function_score": {
                "query": {
                  "term": {
                    "tags.t": {
                      "value": "comedy"
                    }
                  }
                },
                "functions": [
                  {
                    "script_score": {
                      "script": "return doc['tags.w'].value"
                    }
                  }
                ],
                "boost_mode": "replace"
              }
            }
          }
        },
        {
          "nested": {
            "path": "tags",
            "query": {
              "function_score": {
                "query": {
                  "term": {
                    "tags.t": {
                      "value": "drama"
                    }
                  }
                },
                "functions": [
                  {
                    "script_score": {
                      "script": "return doc['tags.w'].value"
                    }
                  }
                ],
                "boost_mode": "replace"
              }
            }
          }
        }
     ]
    }
  }
}

试试这个:

POST book/book/_search
{
    "query": {
        "match": {
           "tags.t": "comedy drama"
        }
    },
    "sort": [
       {
          "tags.w": {
             "order": "desc",
             "mode": "sum"
          }
       }
    ]
}

最新更新