我正在努力让我的嵌套过滤器让标签起作用,
我有一个人实体,这里是
的映射http://localhost:9200/search/person/_mapping
{
"search": {
"mappings": {
"person": {
"_meta": {
"model": "Foo\\CoreBundle\\Entity\\Person"
},
"properties": {
"adresses": {
"type": "nested",
"properties": {
"city": {
"type": "string",
"store": true
}
}
},
"certified": {
"type": "string",
"store": true
},
"completeness": {
"type": "string",
"store": true
},
"fullname": {
"type": "string",
"store": true
},
"lastName": {
"type": "string",
"store": true
},
"name": {
"type": "string",
"store": true
},
"source": {
"type": "string",
"store": true
},
"tags": {
"type": "nested",
"properties": {
"name": {
"type": "string",
"store": true
}
}
},
"type": {
"type": "string",
"store": true
}
}
}
}
}
}
数据似乎填充正确,有一个人实体有以下标记
{
"people": [
{
"id": 13355,
"created_at": "2014-12-27T09:30:54+0100",
"updated_at": "2014-12-27T09:30:54+0100",
"name": "Vorname",
"last_name": "nachname",
"ms": "Anrede",
"title": "Titel",
"source": "Quelle",
"description": "info",
"email": "email",
"language": "EN",
"status": "unready",
"links": [
"link"
],
"tags": [
{
"id": 4176,
"created_at": "2014-12-27T09:30:54+0100",
"updated_at": "2014-12-27T09:30:54+0100",
"name": "position",
"type": "function"
},
{
"id": 4177,
"created_at": "2014-12-27T09:30:54+0100",
"updated_at": "2014-12-27T09:30:54+0100",
"name": "kategorie",
"type": "category"
}
],
"type": "kategorie",
"slug": "vorname_nachname",
"certified": "certified"
}
]
}
你看到有两个名称为“position”和“kategorie”的标签
这是我的代码,我的basequery是fullname属性上的通配符,完美无缺
$finder = $this->container->get('fos_elastica.finder.search.person');
$query = new \Elastica\Query();
$baseQuery=new \Elastica\Query\Wildcard();
$baseQuery->setValue("fullname", "*".trim(mb_strtolower($term))."*", $boost = 1.0);
$nestedFilter = new \Elastica\Filter\Nested();
$termFilter = new \Elastica\Filter\Term();
$termFilter->setTerm("name","position");
$nestedFilter->setPath("tags");
$nestedFilter->setFilter($termFilter);
$baseQuery = new \Elastica\Query\Filtered($baseQuery, $nestedFilter);
$query->setQuery($baseQuery);
$people = $finder->find($query);
这是结果查询:
elastica.INFO: search/person/_search (GET) 3.30 ms
{
"query": {
"filtered": {
"query": {
"wildcard": {
"fullname": {
"value": "**",
"boost": 1
}
}
},
"filter": {
"nested": {
"path": "tags",
"filter": {
"term": {
"name": "position"
}
}
}
}
}
},
"size": "10",
"from": 0
}
但是没有结果,如果我遗漏了嵌套的术语过滤器,它可以工作
知道我做错了什么吗?这是我的orm-mapping:
/**
* @ORM\ManyToMany(targetEntity="Foo\CoreBundle\Entity\Tag", inversedBy="tags")
* @ORM\JoinTable(name="person_has_tags")
**/
private $tags;
答案 0 :(得分:1)
所以我几个月前自己遇到了这个问题。长话短说,弹性搜索索引正在分解你的标签的名称,所以"位置"不再完全匹配。弹性搜索在其中的索引实际上更接近于" pos","它"和"""您需要让弹性搜索知道当您将对象交给索引时知道分解该字段,或者您只是通过标记的ID而不是名称来搜索。我最终选择了id路线,因为它对我来说似乎更有效率。
这里是我的代码作为示例,请注意我将嵌套过滤器嵌入到bool过滤器中,因为我有其他搜索参数,我没有在这里显示:
$query = new Query\QueryString('*' . $searchText .'*');
$boolFilter = new Bool();
$nestedFilter = new Nested();
$nestedFilter->setPath('categories');
$categoryFilter = new Term(['id' => $categoryId]);
$nestedFilter->setFilter($categoryFilter);
$boolFilter->addMust($nestedFilter);
$filteredQuery = new Filtered($query, $boolFilter);
和我弹性物品的片段:
"name": "Sample Object",
"published": true
"categories": [
{
"id": 1,
"name": "cool"
},
{
"id": 3,
"name": "awesome"
}
]