【问题标题】:ElasticSearch for terms with spacesElasticSearch 搜索带空格的术语
【发布时间】:2013-01-15 08:33:08
【问题描述】:

我们正在运行 ElasticSearch,但在搜索包含空格的术语时遇到了一些问题。一个具体的例子:有一个名叫 JM Bruno 的人,但是在搜索这个时没有返回任何结果。我依稀记得搜索这个确切的词确实返回了结果,但我现在无法重现。

我尝试在我的分词器模式中添加空格和“\”,但运气不佳。 ES 设置如下(在 Ruby on Rails 应用程序中使用 Tire gem)

module Search
def self.included base
base.send :include, Tire::Model::Search
base.send :include, Tire::Model::Callbacks

base.class_eval do
  settings  analysis: {
              filter: {
                ngram: {
                  type: 'nGram',
                  max_gram: 12,
                  min_gram: 3
                },
                url_stop: {
                  type: "stop",
                  stopwords: %w[http https]
                }
              },
              tokenizer: {
                url_email_tokenizer: {
                  pattern: '[^\w\-\.@]+',
                  type: 'pattern'
                }
              },
              analyzer: {
                url_analyzer: {
                  tokenizer: "url_email_tokenizer",
                  filter: %w[url_stop ngram],
                  type: "custom"
                },
                name_analyzer: {
                  tokenizer: 'url_email_tokenizer',
                  filter: 'ngram',
                  type: 'custom'
                }
              }
            }


    end
  end
end

我们也使用这些标记器来搜索域名和电子邮件地址。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    尝试使用您应用于您的领域的分析器运行_analyze API

    curl -XGET 'localhost:9200/_analyze?analyzer=name_analyzer' -d 'JM Bruno'
    

    您将看到 Elasticsearch 如何将您的字段内容分解为标记,以及为什么您不能使用 TermQuery 搜索它。 TermQuery 不会被分析,因此它会将您的查询与倒排索引进行完全一样的比较。

    【讨论】:

    • 它返回一个 400 代码,错误为“找不到分析器”。当涉及到分析器时,ES 不知道我在轮胎 gem 中使用什么设置吗?
    • 试试 MyModel.index.analyze “我的文字”,分析器:“name_analyzer”
    • 发现我需要添加索引,但响应对我来说意义不大。当然,它会找到一堆标记,因为我希望它们被 ngram 标记,但这并不能解释为什么它不包含在搜索中(至少,我不清楚)
    【解决方案2】:

    可以使用

    来代替术语查询

    在 Java 中使用高级休息客户端

    query.must((QueryBuilders.matchQuery("name", searchMap.get("JM Bruno")).minimumShouldMatch("100%")));
    

    直接在弹性搜索中

    GET /_搜索

    {
        "query": {
            "match" : {
                "name" : {
                    "query" : "JM Bruno",
                    "cutoff_frequency" : 0.001
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我使用的是 Django,但我将分析器设置为“关键字”时遇到了这个错误。就是这样。默认情况下,它使用“标准”分析器。

      它不会在空格的基础上生成标记。它会将您的整个文本视为一个标记。默认限制为最多 256 个字符。

      这是我的代码。我使用了elasticsearch_dsl。这是我的 document.py 文件

      from django_elasticsearch_dsl import Document, fields
      from elasticsearch_dsl import analyzer
      from .models import Job
      
      html_strip = analyzer(
          'html_strip',
          tokenizer= 'keyword',
          filter=['lowercase'],
      )
      
      @registry.register_document
      class MyDocument(Document):
          title = fields.TextField(
              analyzer=html_strip,
              fields={'raw': fields.KeywordField()}
          )
      
      class Index:
          name = 'jobs'  # Name of Elasticsearch index
          settings = {
              'number_of_shards': 1,
              'number_of_replicas': 0
          }
      
      class Django:
          model = Job
          fields = [
              'salary_min',
              'salary_high'
          ]
      

      这是我的 view.py 文件。在这里,我正在查询搜索对象。这里我使用了一个函数,其中传递了需要搜索的关键字。

      def search_job_titles_for_autocomplete(keyword):
          autocomplete = list()
          search = f"*{keyword}*"
      
          queryset = JobDocument.search().query('wildcard', title=search)
          
          for job in queryset:
              job_to_dict = job.to_dict()
              autocomplete.append(job_to_dict["title"])
      
      return autocomplete
      

      它返回标题列表,我的问题就解决了。

      【讨论】:

        【解决方案4】:

        你需要设置一个multi-field type

        也看看这个很酷的tutorial

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题,我唯一想到的就是用“?”替换空格字符。通配符。看起来默认标记器以及我在查询字符串搜索中特别请求的标记器被忽略了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-09
            • 1970-01-01
            • 1970-01-01
            • 2014-08-03
            • 2014-09-02
            相关资源
            最近更新 更多