我正在努力让我的嵌套过滤器让标签工作,
我有一个个人实体,这是它的映射
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"
}
]
}
你看到有两个标签,名称为"位置"和"凯特戈里"
这是我的代码,我的基本查询是全名属性上的通配符,效果很好
$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映射:
/**
* @ORM'ManyToMany(targetEntity="Foo'CoreBundle'Entity'Tag", inversedBy="tags")
* @ORM'JoinTable(name="person_has_tags")
**/
private $tags;
所以我几个月前自己实际上遇到了这个问题。 长话短说,弹性搜索索引正在分解标签的名称,因此"位置"不再完全匹配。 弹性搜索在其索引中的内容实际上更接近"pos","it"和"tion" 您要么需要让弹性搜索知道在将对象交给索引时知道分解该字段,要么只是按标签的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"
}
]