Шина тестирования единицы измерения (Elastic Search) - Фильтрация результатов методом от to_indexed_json

80
8

Я тестирую свои запросы 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_tags включены с помощью User.last.to_indexed_json:

{"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. Это обновляется по индексу, используя:

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

В результатах поиска я могу увидеть массив location_users. Не имеет смысла для меня, почему другие полиморфные отношения не будут работать.

- EDIT 2 -

Я исправил это, поставив это в свой тест:

User.index.import User.all
sleep 1

Что глупо. И я не совсем понимаю, почему это работает. Зачем?!

спросил(а) 2013-08-07T12:58:00+04:00 7 лет, 1 месяц назад
1
Решение
70

Эластичный поиск по умолчанию обновляет индексы один раз в секунду.

Это важная вещь, потому что внесение изменений в Lucene (использование ES под капотом) может быть довольно дорогостоящей операцией.

Если вам необходимо обновить его сразу, включите refresh = true в URL-адрес при вставке документов. Обычно вы этого не требуете, поскольку каждый раз, когда вставлять много документов, стоит дорого, но модульное тестирование - это один из тех случаев, когда вы хотите его использовать.

Из документации:

обновление

Чтобы обновить индекс сразу после операции, чтобы документ сразу появился в результатах поиска, параметр обновления может быть установлен в значение true. Установка этого параметра в true должна выполняться ТОЛЬКО после тщательной проверки и проверки, что это не приводит к низкой производительности, как от индексации, так и от точки поиска. Обратите внимание: получение документа с использованием API get полностью в реальном времени.

ответил(а) 2013-08-07T16:38:00+04:00 7 лет, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема