首页 > 解决方案 > ES 建议,搜索索引项中的所有单词(不仅是第一个单词)

问题描述

基于这个答案(第一个选项)我创建了这个索引:

    'settings' => array(
        'analysis' => array(
            'analyzer' => array(
                'stop_analyzer' => array( 
                    'type' => 'custom',
                    'tokenizer' => 'standard',
                    'filter' => array(
                        'lowercase',
                        'english_stop'
                    )
                )
            ),
            "filter" => array(
                "english_stop" => array(
                    "type" => "stop",
                    "stopwords" => "_english_"
                )
            )
        )
    ),
    'mappings' => array(
        'properties' => array(
            'texts' => array(
                'type' => 'completion',
                "analyzer" => "stop_analyzer",
                "search_analyzer" => "stop_analyzer", 
                'preserve_position_increments' => false
            ),
        ),
    )

当我开始使用或不使用停用词的建议搜索时,这非常有效。但是,例如,当我在 index: 中有这个时This is the text,我搜索text我不会得到任何结果,那么正确的方法是什么?我宁愿不使用 N-gram。

我的搜索查询:

'suggest' => array(
    'suggestion' => array(
        'prefix'=> 'text',
        'completion' => array(
            'field' => 'texts'
        )
    )
)

标签: elasticsearchelasticsearch-query

解决方案


根据用户给出的评论,添加另一个答案,用于使用 n-gram 搜索所有单词。以前的方法效果很好,但是使用正则表达式非常昂贵。

添加具有索引映射、索引数据、搜索查询和搜索结果的工作示例

索引映射:

{
  "settings": {
    "analysis": {
      "filter": {
        "my_custom_stop_words_filter": {
          "type": "stop",
          "ignore_case": true,
          "stopwords": [
            "and",
            "is",
            "the"
          ]
        },
        "ngram_filter": {
          "type": "ngram",
          "min_gram": 4,
          "max_gram": 20
        }
      },
      "analyzer": {
        "ngram_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "ngram_filter",
            "my_custom_stop_words_filter"
          ]
        }
      }
    },
    "max_ngram_diff": 50
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ngram_analyzer",
        "search_analyzer": "standard"
      }
    }
  }
}

分析 API

POST/_analyze
{
  "analyzer" : "ngram_analyzer",
  "text" : "This is the text"
}

生成以下令牌:

{
    "tokens": [
        {
            "token": "this",
            "start_offset": 0,
            "end_offset": 4,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "text",
            "start_offset": 12,
            "end_offset": 16,
            "type": "<ALPHANUM>",
            "position": 3
        }
    ]
}

指数数据:

{
  "title": [
    "This is the text"
  ]
}

搜索查询:

{
    "query": {
        "match": {
           "title": "text"
        }
    }
}

搜索结果:

"hits": [
            {
                "_index": "stof_29753971",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.41978103,
                "_source": {
                    "title": [
                        "This is the text"
                    ]
                }
            }
        ]

推荐阅读