簡體   English   中英

Elasticsearch-匹配更多單詞時文檔得分更高

[英]Elasticsearch - Document better score when more words matching

我有問題,希望任何人都能幫助我。

我有一個使用匹配查詢進行搜索的簡單示例

"query": {
    "match": {
        "filterValues": "ordner ohne griffloch"
    }
}

我剛好有兩個熱門歌曲:

"hits" : [
  {
    "_index" : "filters",
    "_type" : "filter",
    "_id" : "F-114150068-1170182",
    "_score" : 5.420828,
    "_source" : {
      "filterValues" : [
        "Ja",
        "Griffloch vorhanden",
        "Griffloch",
        "mit Griffloch"
      ]
    },
    "highlight" : {
      "filterValues" : [
        "<em>Griffloch</em>"
      ]
    }
  },
  {
    "_index" : "filters",
    "_type" : "filter",
    "_id" : "F-114150069-1170182",
    "_score" : 4.452639,
    "_source" : {
      "filterValues" : [
        "ohne Griffloch",
        "kein Griffloch",
        "Nein"
      ]
    },
    "highlight" : {
      "filterValues" : [
        "<em>ohne Griffloch</em>"
      ]
    }
  }
]

我的問題是:我想找到第二個匹配的“ ohne Griffloch”作為第一匹配(更好的分數),因為它匹配更多的單詞。 但是我認為第一個得分更高,因為它包含的“格里夫洛奇”更多。

我不能使用術語查詢,因為當查詢包含其他單詞(此處為“ ordner”)時,由於找不到與之完全匹配的內容,因此找不到任何東西。

有什么想法嗎?

謝謝!

有關信息,索引配置:

"settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": [
            "lowercase"
          ]
        },
        "lowercase_shingle": {
          "tokenizer": "whitespace",
          "filter": [
            "lowercase",
            "my_shingle"
          ]
        }
      },
      "filter": {
        "my_shingle": {
          "type": "shingle",
          "min_shingle_size": 2,
          "max_shingle_size": 4
        }
      }
    }
  },
  "mappings": {
    "filter": {
      "properties": {
        "filterValueId": {
          "type": "long"
        },
        "filterValues": {
          "type": "text",
          "position_increment_gap": 100,
          "analyzer": "default",
          "search_analyzer": "lowercase_shingle"
        },
        "categoryId": {
          "type": "long"
        }
      }
    }
  }

您應該在查詢中的短語匹配上增加一個關鍵詞。 因此,自然會提高在多個filterValues之一中找到所有查詢詞的文檔。

但是您需要注意這一怪癖( 請參閱此處,官方文檔

我不知道該怎么做(也許是力量在您身邊),但是您的映射對於position_increment_gap已經正確,但是您應該刪除該設置

search_analyzer”:“小寫字母”

在您的情況下似乎有些奇怪。

然后我們在匹配詞組上添加增強

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "filterValues": "ordner ohne griffloch"
                    }
                }
            ],
            should: [
              {
                "match_phrase": {
                        "filterValues": {
                          "query": "ordner ohne griffloch",
                          "slop": 10 
                        }

                    }
                }
            ]
        }
    }
}

希望它能起作用!

評論后編輯:

如果更改映射,則在索引時間使用shingle_analyzer添加一個子字段

"mappings": {
    "filter": {
      "properties": {
        "filterValueId": {
          "type": "long"
        },
        "filterValues": {
          "type": "text",
          "position_increment_gap": 100,
          "analyzer": "default",
          "search_analyzer": "lowercase_shingle",
          "fields": {
              "shingled": {
                   "type": "text",
                   "analyzer": "lowercase_shingle",
              }
          }
        },
        "categoryId": {
          "type": "long"
        }
      }
    }
  }

然后,您可以使用此查詢在帶狀線子字段上添加增強功能

{
        "query": {
            "bool": {
                "must": [
                    {
                        "match": {
                            "filterValues": "ordner ohne griffloch"
                        }
                    }
                ],
                should: [
                  {
                    "match": {
                            "filterValues.shingled": "ordner ohne griffloch" 
                        }
                    }
                ]
            }
        }
    }

它將在您的示例中提升第二個文檔,而不是第一個文檔

我通過使用帶有自定義腳本的函數得分查詢輕松解決了問題。

該腳本將成為完整的搜索詞,並執行以下兩項操作:根據值的長度設置分數(因此,“ ohne griffloch”大於“ griffloch”,因此更好)。

第二個(可選的,但對我來說是好的)是,它使用值在文本中的位置。

我需要做的是,刪除值的數組,並將每個值作為一個文檔放入索引中。

"functions": [
              {

                "script_score": {
                  "script": {
                    "source": "def v=doc['filterValue'].value; def score = 10000; score += v.length(); score -= \"ordner ohne griffloch\".indexOf(v)*50;",
                    "lang": "painless"
                  }
                }
              }
            ],
            "score_mode": "multiply",
            "boost_mode": "replace",
            "max_boost": 3.4028235e+38,
            "boost": 1
          }

  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM