【问题标题】:Unit Testing Tire (Elastic Search) - Filtering Results with Method from to_indexed_json单元测试轮胎(弹性搜索) - 使用来自 to_indexed_json 的方法过滤结果
【发布时间】:2013-08-07 21:38:39
【问题描述】:

我正在测试我的 Tire / ElasticSearch 查询,但我在 to_indexed_json 中包含的自定义方法存在问题。出于某种原因,它看起来没有被正确索引 - 或者至少我无法使用它进行过滤。

在我的开发环境中,我的过滤器和构面工作正常,我得到了预期的结果。但是在我的测试中,我不断看到零结果。我无法弄清楚我哪里出错了。

我有以下几点:

def to_indexed_json
 to_json methods: [:user_tags, :location_users]
end

我的 user_tags 方法如下所示:

def user_tags
  tags.map(&:content) if tags.present?
end

标签是与我的用户模型的多态关系:

has_many :tags, :as => :tagable

我的搜索块如下所示:

def self.online_sales(params)
  s = Tire.search('users') { query { string '*' }}
    filter = []
    filter << { :range => { :created_at => { :from => params[:start], :to => params[:end] } } }
    filter << { :terms => { :user_tags => ['online'] }}
    s.facet('online_sales') do
      date :created_at, interval: 'day'
      facet_filter :and, filter
    end
  end
end

我已经使用 User.last.to_indexed_json 检查了 user_tags 是否包含在内:

{"id":2,"username":"testusername", ... "user_tags":["online"] }

在我的开发环境中,如果我运行以下查询,我会得到我的用户每天的在线销售列表:

@sales = User.online_sales(start_date: Date.today - 100.days).results.facets["online_sales"]


"_type"=>"date_histogram", "entries"=>[{"time"=>1350950400000, "count"=>1, "min"=>6.0, "max"=>6.0, "total"=>6.0, "total_count"=>1, "mean"=>6.0}, {"time"=>1361836800000, "count"=>7, "min"=>3.0, "max"=>9.0, "total"=>39.0, "total_count"=>7, "mean"=>#<BigDecimal:7fabc07348f8,'0.5571428571 428571E1',27(27)>}....

在我的单元测试中,除非我删除分面过滤器,否则我得到零结果..

{"online_sales"=>{"_type"=>"date_histogram", "entries"=>[]}}

我的测试如下所示:

it "should test the online sales facets", focus: true do
  User.index.delete
  User.create_elasticsearch_index
  user = User.create(username: 'testusername', value: 'pass', location_id: @location.id)  
  user.tags.create content: 'online'  
  user.tags.first.content.should eq 'online'
  user.index.refresh
  ws = User.online_sales(start: (Date.today - 10.days), :end => Date.today) 
  puts ws.results.facets["online_sales"]
end

我是否遗漏了什么、做错了或只是误解了让这件事通过?提前致谢。

-- 编辑--

这似乎与标签关系有关。我有另一种方法,** location_users ** 这是一个 has_many through 关系。这是使用以下索引更新的:

def location_users
  location.users.map(&:id)
end

搜索时,我可以在结果中看到一组 location_users。我不明白为什么其他多态关系不起作用..

-- 编辑 2--

我已经通过在测试中解决了这个问题:

User.index.import User.all
sleep 1

这很愚蠢。而且,我真的不明白为什么会这样。为什么?!

【问题讨论】:

    标签: ruby-on-rails elasticsearch tire


    【解决方案1】:

    默认情况下,弹性搜索每秒更新一次它的索引。

    这是一个性能问题,因为将您的更改提交到 Lucene(ES 在后台使用)可能是一项非常昂贵的操作。

    如果您需要在插入文档时立即更新,请在 URL 中包含 refresh=true。您通常不希望这样做,因为每次插入大量文档时都提交成本很高,但单元测试是您确实想要使用它的情况之一。

    来自文档:

    刷新

    要在操作发生后立即刷新索引,使文档立即出现在搜索结果中,可以将refresh参数设置为true。将此选项设置为 true 仅应在仔细考虑并验证它不会导致性能不佳(从索引和搜索的角度来看)之后进行。请注意,使用 get API 获取文档是完全实时的。

    【讨论】:

    • 我同意和不同意你的看法。根据这个bitsandbit.es/post/11295134047/… 使用 user.index.refresh 应该足够了。而且,在我所有的其他测试中,这都很好。不开心的只是多态的。
    • 嗯 ...如果添加 1 秒的等待确实可以解决问题,那么您的更改尚未提交。您可以在运行其余测试之前尝试对索引进行显式刷新吗?不知道如何使用轮胎,但这是等效的 curl 命令:curl -XPOST 'http://localhost:9200/twitter/_refresh'
    • 关键是用户实际上被索引了,它似乎不是标签。我们可以在 ES 中看到用户记录。 index.refresh 在我们不使用多态关系时起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 2013-07-27
    • 1970-01-01
    相关资源
    最近更新 更多