【问题标题】:Elasticsearch not sure if i need to use a bool queryElasticsearch 不确定我是否需要使用 bool 查询
【发布时间】:2015-04-23 06:09:31
【问题描述】:

我正在为我的 Laravel 应用程序使用 ES,但我不确定是否需要使用 bool 查询。

在我的查询中我需要做的:

“标题”字段的全文搜索

检查“价格”字段是否介于 1 - 9999 之间的过滤器

检查“状态”字段是否等于 1 的过滤器。

那么我需要对上面的内容进行布尔查询吗?将标题和状态设置为(必须),将价格设置为(应该)

或者我可以简单地做一些类似的事情:

 'filtered' => [
    'filter' => [
      ['term' => [ 'status' =>  1] ],
                            [ 'range' => [
                                    'price' => [
                                        'gte' => 1,
                                        'lte' => 99999,
                                    ]
                                ]
    ],
    'query' => [
      'match' => Input::get('query', ''),
      ],
    ],
  ],

或更新:

'filtered' => [
                'query' => [
                    'match' => ['title' => Input::get('query')]
                ],
                'filter'=> [
                    'bool' => [
                        'must' => [
                            ['term' => [ 'active' =>  1] ],
                            [ 'range' => [
                                    'price' => [
                                        'gte' => 1,
                                        'lte' => 99999,
                                    ]
                                ]
                            ]
                        ]
                    ]
                ],
            ],

【问题讨论】:

    标签: php mysql search laravel elasticsearch


    【解决方案1】:

    您的设置(理论上)是正确的,但语法有点偏离。先说理论:

    查询用于确定评分和相关性。查询基本上决定了文档的排名和返回的顺序。

    过滤器是简单的包含/排除标准。如果文档与过滤器匹配,则将包含在结果中。如果它不匹配......它不包括在内。由于过滤器不执行任何评分,因此它们的速度要快得多(并且可以轻松缓存)。

    因此,请使用过滤器来满足简单的包含/排除标准。并对需要影响分数的任何内容(如全文搜索)使用查询。

    这意味着您的查询完全正确。但是语法需要一些调整:

    'filtered' => [
        'filter' => [
          'bool' => [
             'must' => [
                ['term' => [ 'status' =>  1] ], 
                [ 
                   'range' => [
                      'price' => [
                          'gte' => 1,
                          'lte' => 99999,
                      ]
                   ] 
                ]
             ]               
          ]
      ],
      'query' => [
          'match' => [
            'title' => Input::get('query', '')
          ]
       ]
    ]
    

    基本上,filtered 查询的 filter 子句接受单个过滤器。由于您需要定义两个过滤器(termrange),因此您需要使用复合bool 过滤器将它们组合在一起。否则,您的语法是正确的。

    另外,您忘记了 match 查询中的“标题”字段

    注意:我不确定 laravel 在 ES 集成方面是如何工作的,但您可能还需要将整个东西放在 query 块中。

    【讨论】:

    • 谢谢@Zach 如果您有时间看,我还更新了第二个查询。它工作完美我只是想确保我在“最佳实践”之后写它
    • 好吧,我的“过滤”正在包装整个查询。它仍然可以正常工作,但现在确定它是否是最好的方法
    • 您更新后的查询对我来说看起来不错!这种设置——过滤+查询/过滤部分——绝对是理想的、最佳实践的做事方式。
    • 好吧,干杯@Zach!我不得不问,因为我看到很多人要么将 quey -> match - 文本放在“已过滤”内,而将一些放在已过滤​​外。像我的和你的一样:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多