使用ElasticSearch和Tire过滤关联的ID

时间:2012-10-17 15:23:16

标签: activerecord elasticsearch tire

我已经在很长一段时间内对付一个简单的查询了。我在StackOverflow上查看了所有文档和示例,以及关于Tire的大多数问题但没有成功。

基本上,我正在尝试根据某些关联模型的ID过滤搜索结果。

这是模型(注意我目前仍然使用动态映射):

class Location < ActiveRecord::Base
  belongs_to :city
  has_and_belongs_to_many :tags

  # also has a string attribute named 'kind'
end

我要做的是按city_idtag_idkind过滤我的搜索查询。

我已经尝试构建查询,但我只是因为我似乎无法正确构建它而得到错误。这是我到目前为止(不工作):

Location.search do
  query { string params[:query] } if params[:query].present?
  filter :term, { city_id: params[:city_id] } if params[:city_id].present? # I'd like to use the ids filter, but have no idea of the syntax I'm supposed to use
  filter :ids, { 'tag.id', values: [params[:tag_id]] } if params[:tag_id].present? # does not compile
  filter :match, { kind: params[:kind] } if params[:kind].present? # does not compile either
end

1 个答案:

答案 0 :(得分:3)

事实证明,动态映射并没有为这种情况削减它。我还必须定义我的数据的索引方式。

这是我的映射:

mapping do
  indexes :id, index: :not_analyzed
  indexes :kind, index: :not_analyzed
  indexes :city_id, index: :not_analyzed
  indexes :tags do
    indexes :id, index: :not_analyzed
  end
end

和我的自定义to_indexed_json

def to_indexed_json
  {
    kind: kind,
    city_id: city_id,
    tags: tags.map do |t|
      {
        id: t.id
      }
    end
  }.to_json
end

最后,我可以这样过滤:

  Location.search do
    query { string params[:query] } if params[:query].present?
    filter :term, { city_id: params[:city_id] } if params[:city_id].present?
    filter :term, { "tags.id" => params[:tag_id] } if params[:tag_id].present?
    filter :term, { kind: params[:kind] } if params[:kind].present?
  end

重要的部分是标记索引,它允许我在过滤器中使用"tags.id"