我在使用FOQElasticaBundle
构建查询时遇到问题我有3个实体
用户可以拥有1个或更多酒店,每个酒店只有1个氛围。 在我的配置文件中,我有:
foq_elastica:
clients:
default: { host: %elasticsearch.host%, port: %elasticsearch.port% }
indexes:
MyBundle:
client: default
finder:
types:
user:
mappings:
id:
boost: 10
analyzer: fr_case_analyzer
name:
boost: 5
analyzer: fr_case_analyzer
hotels:
type: "nested"
properties:
name:
boost: 10
analyzer: fr_case_analyzer
ambiance:
boost: 1
我希望能够通过输入他的姓名或酒店名称来搜索用户,并可能在Ambiance类型上添加过滤器。 所以查询看起来应该是这样的:
$mainQuery = new \Elastica_Query_Bool();
$nameQuery = new \Elastica_Query_Bool();
$filtersQuery = new \Elastica_Query_Bool();
//searching in Users' names
$nameQuery = new \Elastica_Query_Text();
$nameQuery->setFieldQuery('name', $searchName);
$nameQuery->setFieldParam('name', 'boost', 5);
$nameQuery->setFieldParam('name', 'type', 'phrase_prefix');
//searching in Hotels' names
$hotelNameQuery = new \Elastica_Query_Text();
$hotelNameQuery->setFieldQuery('name', $searchName);
$hotelNameQuery->setFieldParam('name', 'boost', 3);
$hotelNameQuery->setFieldParam('name', 'type', 'phrase_prefix');
$nestedHotelNameQuery = new \Elastica_Query_Nested();
$nestedHotelNameQuery->setPath('hotels');
$nestedHotelNameQuery->setQuery($hotelNameQuery);
$nameQuery->addShould($nameQuery);
$nameQuery->addShould($nestedHotelNameQuery);
//if filter on ambiance
$ambianceQuery = new \Elastica_Query_Term();
$ambianceQuery->setTerm('ambiance', $arrFilters['ambiance']);
$nestedAmbianceQuery = new \Elastica_Query_Nested();
$nestedAmbianceQuery->setPath('hotels');
$nestedAmbianceQuery->setQuery($ambianceQuery);
$filtersQuery->addMust($nestedAmbianceQuery);
//adding the parameters to the main query
$mainQuery->addMust($nameQuery);
$mainQuery->addMust($filtersQuery);
不幸的是,如果Ambiance过滤器被激活,这不起作用并且不返回任何结果,但如果我只搜索名称,则效果很好。
我做错了什么?
答案 0 :(得分:0)
我发现为什么它不起作用。 该包实际上在对象上使用__toString()。 因此,我没有查询环境的“id”,而是修改了我的html输入,因此值是环境的名称。
答案 1 :(得分:0)
这是我自己的解决方案版本:
根据elasticsearch文档,我们应该实现一个对json声明的结构:
{
"query": {
"bool": {
"must": [
{ "match": { "title": "eggs" }},
{
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "match": { "comments.name": "john" }},
{ "match": { "comments.age": 28 }}
]
}}}}
]
}}}
所以要使用symfony 2执行此操作,根据FOSElasticaBundle包,我们将生成以下代码行:
//if filter on ambiance
$ambianceQuery = new \Elastica_Query_Term();
$ambianceQuery->setTerm('ambiance', $arrFilters['ambiance']);
// We will add the the term to the query bool
$filtersQuery->addMust($ambianceQuery)
$nestedAmbianceQuery = new \Elastica_Query_Nested();
$nestedAmbianceQuery->setPath('hotels');
// we will set the result as argument in the setQuery method.
$nestedAmbianceQuery->setQuery($filtersQuery);
// And finally we add the nested query to the main query bool through addMust.
$mainQuery->addMust($nestedAmbianceQuery);
希望能帮助他人。
A +
答案 2 :(得分:-1)
刚遇到同样的问题。这对我有用:
..
$ambianceQuery->setTerm('hotels.ambiance', $arrFilters['ambiance']);
..
在Symfony2的FOQElasticaBundle(现在是FOSElasticaBundle)中没有找到任何关于此的示例,但它应该像这样的弹性搜索查询结束:
http://www.elasticsearch.org/guide/reference/query-dsl/nested-query/
可以这样做/测试原始弹性搜索查询:
$queryString = '{..JSON..}';
$boolQuery = new \Elastica_Query_Builder($queryString);