Elasticsearch 中可选的自父关系
Optional Self-Parent Relation in Elasticsearch
我有一个 Symfony2 项目,我正在尝试使用 Elasticsearch 实现搜索功能。
我的问题是,我需要为具有可选自关系的实体编制索引。这意味着我的 Item 实体有一个 "parent" 字段,引用另一个 Item。
为了进行搜索,我想在 "parent" 字段上创建过滤器。 我的 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
)
此命令returns以下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))
);
我认为这个解决方案有局限性(我假设是针对多级育儿),但对于这种需要,它是有效的。
我有一个 Symfony2 项目,我正在尝试使用 Elasticsearch 实现搜索功能。
我的问题是,我需要为具有可选自关系的实体编制索引。这意味着我的 Item 实体有一个 "parent" 字段,引用另一个 Item。
为了进行搜索,我想在 "parent" 字段上创建过滤器。 我的 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
)
此命令returns以下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))
);
我认为这个解决方案有局限性(我假设是针对多级育儿),但对于这种需要,它是有效的。