2

我在使用 FOQElasticaBundle 构建查询时遇到问题

我有 3 个实体

  • 用户
  • 酒店
  • 氛围

用户可以拥有 1 个或多个 Hotels,每个 Hotel 只有 1 个 Ambiance。在我的配置文件中,我有:

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 过滤器,这不起作用并且不返回任何结果,但如果我只使用名称进行搜索,则效果很好。

我做错了什么?

4

3 回答 3

0

我找到了为什么它不起作用。捆绑包实际上在对象上使用了 __toString()。因此,我没有查询环境的“id”,而是修改了我的 html 输入,因此值是环境的名称。

于 2013-04-29T07:54:15.510 回答
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);

希望这会帮助别人。

一个+

于 2016-02-22T10:51:14.813 回答
-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);
于 2013-04-04T06:57:56.830 回答