搜索操作
编辑搜索操作编辑
嗯... 它被称为 Elasticsearch 并非浪得虚名!让我们来谈谈客户端中的搜索操作。
客户端允许您完全访问 REST API 公开的每个查询和参数,并尽可能遵循其命名方案。让我们看几个例子,以便您熟悉语法。
匹配查询编辑
这是一个标准的 curl 匹配查询
curl -XGET 'localhost:9200/my_index/_search' -d '{ "query" : { "match" : { "testField" : "abc" } } }'
这是在客户端中构建的相同查询
$params = [ 'index' => 'my_index', 'body' => [ 'query' => [ 'match' => [ 'testField' => 'abc' ] ] ] ]; $results = $client->search($params);
请注意,PHP 数组的结构和布局与 JSON 请求体完全相同。这使得将 JSON 示例转换为 PHP 变得非常简单。检查 PHP 数组(对于更复杂的示例)的快速方法是将其编码回 JSON 并进行检查
$params = [ 'index' => 'my_index', 'body' => [ 'query' => [ 'match' => [ 'testField' => 'abc' ] ] ] ]; print_r(json_encode($params['body'])); {"query":{"match":{"testField":"abc"}}}
搜索结果遵循与 Elasticsearch 搜索响应相同的格式,唯一的区别是 JSON 响应被反序列化回 PHP 数组。处理搜索结果就像迭代数组值一样简单
$params = [ 'index' => 'my_index', 'body' => [ 'query' => [ 'match' => [ 'testField' => 'abc' ] ] ] ]; $results = $client->search($params); $milliseconds = $results['took']; $maxScore = $results['hits']['max_score']; $score = $results['hits']['hits'][0]['_score']; $doc = $results['hits']['hits'][0]['_source'];
布尔查询编辑
使用客户端可以轻松构建布尔查询。例如,此查询
curl -XGET 'localhost:9200/my_index/_search' -d '{ "query" : { "bool" : { "must": [ { "match" : { "testField" : "abc" } }, { "match" : { "testField2" : "xyz" } } ] } } }'
将被构建为如下结构(注意方括号的位置)
$params = [ 'index' => 'my_index', 'body' => [ 'query' => [ 'bool' => [ 'must' => [ [ 'match' => [ 'testField' => 'abc' ] ], [ 'match' => [ 'testField2' => 'xyz' ] ], ] ] ] ] ]; $results = $client->search($params);
请注意,must
子句接受一个数组的数组。这在内部被序列化为一个 JSON 对象数组,因此最终的结果输出与 curl 示例相同。有关 PHP 中数组和对象的更多详细信息,请参阅 处理 PHP 中的 JSON 数组和对象。
更复杂的示例编辑
让我们构建一个稍微复杂的示例:一个包含过滤器和查询的布尔查询。这是 Elasticsearch 查询中非常常见的操作,因此这将是一个很好的演示。
查询的 curl 版本
curl -XGET 'localhost:9200/my_index/_search' -d '{ "query" : { "bool" : { "filter" : { "term" : { "my_field" : "abc" } }, "should" : { "match" : { "my_other_field" : "xyz" } } } } }'
在 PHP 中
$params = [ 'index' => 'my_index', 'body' => [ 'query' => [ 'bool' => [ 'filter' => [ 'term' => [ 'my_field' => 'abc' ] ], 'should' => [ 'match' => [ 'my_other_field' => 'xyz' ] ] ] ] ] ]; $results = $client->search($params);
滚动编辑
Elasticsearch 的滚动功能用于批量分页浏览大量文档,例如导出属于单个用户的所有文档。它比常规搜索更有效,因为它不需要维护昂贵的优先级队列来对文档进行排序。
滚动的工作原理是维护索引的“时间点”快照,然后用于分页。即使存在后台索引/更新/删除操作,此窗口也允许一致的分页。首先,您执行启用了 scroll
的搜索请求。这将返回一“页”文档,以及一个用于继续对匹配结果进行分页的 scroll_id
。
有关滚动的更多详细信息,请参阅 参考文档。
这是一个示例,可以用作更高级操作的模板
$client = ClientBuilder::create()->build(); $params = [ 'scroll' => '30s', // how long between scroll requests. should be small! 'size' => 50, // how many results *per shard* you want back 'index' => 'my_index', 'body' => [ 'query' => [ 'match_all' => new \stdClass() ] ] ]; // Execute the search // The response will contain the first batch of documents // and a scroll_id $response = $client->search($params); // Now we loop until the scroll "cursors" are exhausted while (isset($response['hits']['hits']) && count($response['hits']['hits']) > 0) { // ** // Do your work here, on the $response['hits']['hits'] array // ** // When done, get the new scroll_id // You must always refresh your _scroll_id! It can change sometimes $scroll_id = $response['_scroll_id']; // Execute a Scroll request and repeat $response = $client->scroll([ 'body' => [ 'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id 'scroll' => '30s' // and the same timeout window ] ]); }