8

我们正在运行 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

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

4

5 回答 5

4

尝试使用您应用于字段的分析器运行_analyze API 。

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

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

于 2013-01-15T08:59:44.600 回答
1

我正在使用 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

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

于 2020-12-17T15:26:31.583 回答
1

而不是术语查询,这可以通过使用来搜索

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

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

直接在弹性搜索中

获取 /_搜索

{
    "query": {
        "match" : {
            "name" : {
                "query" : "JM Bruno",
                "cutoff_frequency" : 0.001
            }
        }
    }
}
于 2019-03-26T05:54:43.423 回答
0

您需要设置一个多字段类型

也看看这个非常酷的教程

于 2016-04-10T06:11:15.907 回答
-1

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

于 2014-05-29T19:40:48.233 回答