Поиск рельсов в поисках вложенного поля JSON
Я использую драгоценный камень эластичной модели для модели, которая имеет has_many
отношения. Чтобы соответствовать документации, скажем, модель Article
и отношения has_many categories
, Поэтому я написал клиентский сериализатор следующим образом (прямо из документации):
def as_indexed_json(options={})
self.as_json(
include: { categories: { only: :title},
})
end
Сериализация, кажется, работает. Результат примера статьи as_indexed_json содержит "categories" => {"title"=> "one", "title"=> "two", "title"=> "three"}
блок.
То, с чем я борюсь и не смог найти в документации, - это как искать в этом вложенном поле.
Вот что я попробовал:
Из документации эластичного поиска по вложенному запросу я понял, что это должно выглядеть так:
r = Article.search query: {
nested: {
path: "categories",
query: {match: {title: "one"}}
}
}
но, когда я делаю r.results.first
Я получаю ошибку: nested object under path [categories] is not of nested type]
...
Я попытался добавить изменение одной строки в сериализаторе: include: { categories: { type: "nested", only: :title}
но это ничего не меняет, все равно говорит, что категории не являются вложенными.
Конечно, я попытался просто запросить поле без вложенности, как это:
r = Article.search query: {match: {categories: 'one'}}
Но это просто не дает никаких результатов.
Полнотекстовый поиск вот так:
r = Article.search query: {match: {_all: 'one'}}
Возвращает результаты, но, конечно, я хочу искать только "один" в поле категорий.
Любая помощь приветствуется!
2 ответа
Rails не создает вложенного отображения в asticsearch. Elasticsearch делает категории объектными, а не вложенными дочерними, используя динамическое отображение ("Когда Elasticsearch обнаруживает ранее неизвестное поле в документе, он использует динамическое отображение для определения типа данных для поля и автоматически добавляет новое поле к отображению типа как объект, не вкладывая их "). Для того, чтобы сделать их вложенными объектами, вам нужно снова создать сопоставление в asticsearch с категориями как вложенный тип, типом уведомления как вложенный из категории.
PUT /my_index
{
"mappings": {
"article": {
"properties": {
"categories": {
"type": "nested",
"properties": {
"name": { "type": "string" },
"comment": { "type": "string" },
"age": { "type": "short" },
"stars": { "type": "short" },
"date": { "type": "date" }
}
}
}
}
}
}
После этого вы можете либо переиндексировать данные с клиента, либо, если вы хотите, чтобы нулевое время простоя читалось здесь.
PS: Вы должны удалить старое отображение для определенного индекса перед созданием нового.
Итак, это выглядит так: r = Article.search query: {match: {"categories.title" => 'one'}}
работает, но я оставлю вопрос открытым на тот случай, если кто-то сможет объяснить, что происходит с вложенной вещью...