使用Tire和Ruby on Rails的elasticsearch搜索电子邮件时的结果无效

时间:2013-08-16 22:19:51

标签: ruby-on-rails elasticsearch tire

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

问题在于,如果我搜索:“something@example.com”。因为@和而我得到了奇怪的结果。符号。我通过黑客攻击查询字符串并在字符串之前添加“email:”来“解决”我怀疑是一个字符串。如果我不这样做,当搜索“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

使用“email:”进行搜索时,分析仪工作正常,但没有它,它会在没有指定分析器的情况下在电子邮件中搜索该字符串,从而获得大量不良结果。

2 个答案:

答案 0 :(得分:3)

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

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

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

像这样制作您的搜索查询:

"term": {
    "email": "example@domain.com"
}
祝你好运!

答案 1 :(得分:2)

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

例如:的东西\ @example \ .COM