0

我正在尝试使用 Tire 和 elasticsearch 通过电子邮件进行索引和搜索。

问题是,如果我搜索:“something@example.com”。由于 @ 和 ,我得到了奇怪的结果。符号。我通过破解查询字符串并在我怀疑是字符串的字符串之前添加“电子邮件:”来“解决”。如果我不这样做,在搜索“something@example.com”时,我会得到“something@gmail.com”或“asd@example.com”的结果。

include Tire::Model::Search
include Tire::Model::Callbacks

settings :analysis =>{
          :analyzer => {
            :whole_email => {
              'tokenizer' => 'uax_url_email'
            }
          }
  } do
  mapping do
    indexes :id
    indexes :email, :analyzer => 'whole_email', :boost => 10
  end
end

def self.search(params)
  params[:query] = params[:query].split(" ").map { |x| x =~ EMAIL_REGEXP ? "email:#{x}" : x }.join(" ")
  tire.search(load: {:include => {'event' => 'organizer'}}, page: params[:page], per_page: params[:per_page] || 10) do
    query do
      boolean do
        must { string params[:query] } if params[:query].present?
        must { term :event_id, params[:event_id]  } if params[:event_id].present?
      end
    end
    sort do
      by :id, 'desc'
    end
  end
end

def to_indexed_json
  self.to_json
end

使用“电子邮件:”进行搜索时,分析器可以完美运行,但没有它,它会在没有指定分析器的情况下在电子邮件中搜索该字符串,得到很多不想要的结果。

4

2 回答 2

3

我认为您的问题与该_all领域有关。默认情况下,所有字段都会被索引两次,一次是在字段名下,一次是在字段中使用不同的分析器_all

如果您发送查询时未指定您正在搜索的字段,那么它将针对该_all字段执行。当您为您的文档编制索引时,电子邮件字段内容将在_all字段下再次编制索引(以在您的映射中停止此设置include_in_all: false),在该字段中以标准方式对它们进行标记(在 @ 和 . 上拆分)。这意味着无指导的查询会给出奇怪的结果。

我解决这个问题的方法是使用term电子邮件查询并确保指定要搜索的字段。术语查询更快,因为它没有查询所具有的查询解析步骤query_string(这就是为什么当您在字符串前面加上“email:”时,它会转到正确的字段,这就是查询解析器工作的原因)。此外,您不需要指定自定义分析器,除非您正在索引包含自由文本和 url 和电子邮件的字段。如果该字段仅包含电子邮件,则只需设置index: not_analyzed,它将保持单个令牌。(您可能希望有一个自定义分析器来小写电子邮件。)

像这样进行搜索查询:

"term": {
    "email": "example@domain.com"
}

祝你好运!

于 2013-08-17T12:05:05.633 回答
2

将该字段添加到 _all 并尝试通过将转义字符 (\) 添加到 emailid 的特殊字符来进行搜索。

例如:某事\@example\.com

于 2013-08-19T17:53:25.980 回答