У меня есть проект Symfony2, и я пытаюсь реализовать функцию поиска с помощью Elasticsearch.
Моя проблема в том, что мне нужно индексировать сущность с необязательным отношением к себе. Это означает, что мой Вещь У сущности есть «родительское» поле, ссылающееся на другой Предмет.
Чтобы выполнить поиск, я хочу создать фильтры в этом «родительском» поле. Мой Item.parent равен NULL? например.
Итак, я использую FosElasticaBundle.
Вот мое отображение:
types:
Item:
mappings:
name:
children:
type: object
_parent:
type: Item
parent:
type: object
_routing:
required: false
_parent:
type : Item
identifier: id
property : parent
persistence:
...
model_to_elastica_transformer:
service: core.transformer.item
И трансформатор делает:
$document = new Document();
if (!is_null($item->getParent())) {
$document->setParent($item->getParent()->getId());
} else {
$document->setParent(null);
}
return $document;
И проблема возникает, когда я пытаюсь создать свой индекс ( php app/console fos:elastica:populate
)
Эта команда возвращает следующее ResponseException:
index: /traveler/Item caused RoutingMissingException[routing is required for [traveler]/[Item]/[null]]
У вас есть идеи, почему это не работает? И это хороший способ сделать это?
Спасибо,
Поскольку в этом случае мои потребности довольно просты, нам удалось решить эту проблему.
конфигурация
Вместо использования _parent
поле в конфиге, я использовал вложенное свойство.
Item:
mappings:
children:
type: "nested"properties:
name: ~
parent:
type: "object"
Это дерево, поэтому дочерние и родительские свойства являются Item.
Мне нужно было создать реквизит с фильтром по родительскому значению (равно нулю, равно ли что-то …)
Запрос
Итак, я использовал \ Elasitca \ Filter \ Nested.
Например, когда мне нужно исключить некоторые результаты, основанные на пользователях и языке детей, я могу сделать следующее:
$nestedFilter = new Nested();
$boolFilter = new Bool();
$boolAndFilter = new BoolAnd();
$boolAndFilter
->setFilters(array(
new Term(array("children.user.id" => $this->getClient()->getId())),
new Term(array("children.other" => $language))
))
;
$nestedFilter
->setFilter($boolAndFilter)
->setPath('children')
;
$query = new Filtered(
$query,
new BoolNot($boolFilter->addMust($nestedFilter))
);
Я думаю, что это решение имеет ограничения (для многоуровневого воспитания, я полагаю), но для этого нужно, это работает.
Других решений пока нет …