如何在Elasticsearch中使用ngram时控制结果的评分或排序?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Elasticsearch中使用ngram时控制结果的评分或排序?相关的知识,希望对你有一定的参考价值。

我正在使用Elasticsearch 6.X ..

我创建了一个索引类型为test_index的索引doc,如下所示:

PUT /test_index
{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "tokenizer": "my_ngram_tokenizer"
        }
      },
      "tokenizer": {
        "my_ngram_tokenizer": {
          "type": "nGram",
          "min_gram": "1",
          "max_gram": "7",
          "token_chars": [
            "letter",
            "digit",
            "punctuation"
          ]
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "my_text": {
          "type": "text",
          "fielddata": true,
          "fields": {
            "ngram": {
              "type": "text",
              "fielddata": true,
              "analyzer": "my_analyzer"
            }
          }
        }
      }
    }
  }
}

我索引数据如下:

PUT /text_index/doc/1
{
    "my_text": "ohio"
}
PUT /text_index/doc/2
{
    "my_text": "ohlin"
}
PUT /text_index/doc/3
{
    "my_text": "john"
}

然后我用搜索查询:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "oh",
            "fields": [
              "my_text^5",
              "my_text.ngram"
            ]
          }
        }
      ]
    }
  }
}

并得到了回应:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 5,
    "max_score": 1.0042334,
    "hits": [
      {
        "_index": "test_index",
        "_type": "doc",
        "_id": "1",
        "_score": 1.0042334,
        "_source": {
          "my_text": "ohio"
        }
      },
      {
        "_index": "test_index",
        "_type": "doc",
        "_id": "3",
        "_score": 0.97201055,
        "_source": {
          "my_text": "john"
        }
      },
      {
        "_index": "test_index",
        "_type": "doc",
        "_id": "2",
        "_score": 0.80404717,
        "_source": {
          "my_text": "ohlin"
        }
      }
    ]
  }
}

在这里,我们可以看到当我搜索oh时,我得到了顺序的结果:

-> ohio
-> john
-> ohlin

但是,我希望以一种给匹配前缀提供更高优先级的方式对结果进行评分和排序:

-> ohio
-> ohlin
-> john

我怎样才能达到这样的效果?我可以采取什么方法?提前致谢。

答案

您应该使用edge_ngram标记器添加一个带有新分析器的新子字段,然后在多匹配中添加新子字段。

然后,您需要使用most_fields类型进行多匹配查询。然后,只有从搜索词开始的文档才会在此子字段上匹配,然后将针对匹配文档的其他文档进行提升。

以上是关于如何在Elasticsearch中使用ngram时控制结果的评分或排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何使更短(更接近)的令牌匹配更相关? (edge_ngram)

Elasticsearch:使用 search_analyzer 及 edge ngram 来实现 Search-As-You-Type

Elasticsearch:使用 search_analyzer 及 edge ngram 来实现 Search-As-You-Type

[Elasticsearch] 部分匹配 - 索引期间优化ngrams及索引期间的即时搜索

[Elasticsearch] 部分匹配 - 索引期间优化ngrams及索引期间的即时搜索

elasticsearch ngram 和 postgresql trigram 搜索结果不匹配