Поиск рельсов в поисках вложенного поля 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'}} работает, но я оставлю вопрос открытым на тот случай, если кто-то сможет объяснить, что происходит с вложенной вещью...

Другие вопросы по тегам