搜索操作

好吧,这不叫elasticsearch的不劳而获!让我们来谈谈PHP客户端中的搜索操作。

客户端允许你通过REST API访问所有的查询和公开的参数,尽可能的遵循命名规则。让我们来看一些例子,你就可以熟悉它的语法。

匹配查询

这里是一个标准的匹配查询的curl:

  1. curl -XGET 'localhost:9200/my_index/my_type/_search' -d '{
  2. "query" : {
  3. "match" : {
  4. "testField" : "abc"
  5. }
  6. }
  7. }'

这里是在客户端中=同样查询结构的查询:

  1. $params['index'] = 'my_index';
  2. $params['type']  = 'my_type';
  3. $params['body']['query']['match']['testField'] = 'abc';
  4. $results = $client->search($params);

使用原始JSON

正如你看到的JSON和查询之间的转换是非常简单的。你可以直接序列化JSON到body中,或者甚至提供原始的JSON字符串。客户端会处理的很好:

  1. $json = '{
  2. "query" : {
  3. "match" : {
  4. "testField" : "abc"
  5. }
  6. }
  7. }';
  8. $params['index'] = 'my_index';
  9. $params['type']  = 'my_type';
  10. $params['body']  = $json;
  11. $results = $client->search($params);

搜索结果返回的是简单的由elasticsearch响应元素序列化成的数组。与搜索结果工作就像与迭代数组一样简单:

  1. $milliseconds = $results['took'];
  2. $maxScore     = $results['hits']['max_score'];
  3. $score = $results['hits']['hits'][0]['_score'];
  4. $doc   = $results['hits']['hits'][0]['_source'];

Bool 查询

Bool查询可以使用客户端轻松的构造出来。例如这个查询:

  1. curl -XGET 'localhost:9200/my_index/my_type/_search' -d '{
  2. "query" : {
  3. "bool" : {
  4. "must": {
  5. "match" : {
  6. "testField" : "abc"
  7. },
  8. "match" : {
  9. "anotherTestField" : "xyz"
  10. }
  11. }
  12. }
  13. }
  14. }'

像这样的结构(注意中括号的位置)

  1. $params['index'] = 'my_index';
  2. $params['type']  = 'my_type';
  3. $params['body']['query']['bool']['must'] = array(
  4. array('match' => array('testField' => 'abc')),
  5. array('match' => array('anotherTestField' => 'xyz')),
  6. );
  7. $results = $client->search($params);

一个更复杂的例子

让我们来构造一个稍微复杂的例子:一个过滤的查询包含一个过滤器和一个查询。这在elasticsearch查询中是非常常见的活动,所以,这将是一个好的演示。

curl版本的查询:

  1. curl -XGET 'localhost:9200/my_index/my_type/_search' -d '{
  2. "query" : {
  3. "filtered" : {
  4. "filter" : {
  5. "term" : {
  6. "my_field" : "abc"
  7. }
  8. },
  9. "query" : {
  10. "match" : {
  11. "my_other_field" : "xyz"
  12. }
  13. }
  14. }
  15. }
  16. }'

PHP版本的查询:

  1. $params['index'] = 'my_index';
  2. $params['type']  = 'my_type';
  3. $filter = array();
  4. $filter['term']['my_field'] = 'abc';
  5. $query = array();
  6. $query['match']['my_other_field'] = 'xyz';
  7. $params['body']['query']['filtered'] = array(
  8. "filter" => $filter,
  9. "query"  => $query
  10. );
  11. $results = $client->search($params);

为了清晰和可读性,过滤器和查询部分作为变量被单独分配并且之后组合在一起。这通常对应用程序来说是一个好的设计模式,因为它可以让你对待你的查询和过滤器想构建块一样,可以通过你的应用程序传递。

当然,在最后,他被构建在一个简单的数组中。你可以轻松构建整个数组在一个定义的嵌套数组块中,或者一行一行的构建。

所有客户端需要一个关联数组,并且结构要和JSON查询结构匹配。

Function_Score 查询

有一点需要特别注意关于function_score 查询。由于PHP处理JSON编码,一切都被转换成了数组的这种活那种形式。这通常不是问题,因为Elasticsearch API中大多地方接受数组或互换空对象。

然而,function_score 稍有不同,需要区分空数组和空对象,例如,考虑如下查询:

  1. {
  2. "query":{
  3. "function_score":{
  4. "functions":[
  5. {
  6. "random_score":{}
  7. }
  8. ],
  9. "boost_mode":"replace",
  10. "query":{
  11. "match_all":{}
  12. }
  13. }
  14. }
  15. }

function_score定义一个数组对象,random_score 用空对象作为值。

PHP的json_encode会转换查询到这种形式:

  1. {
  2. "query":{
  3. "function_score":{
  4. "functions":[
  5. {
  6. "random_score":[]
  7. }
  8. ],
  9. "boost_mode":"replace",
  10. "query":{
  11. "match_all":[]
  12. }
  13. }
  14. }
  15. }

这样会导致一个解析异常。我们需要做的是告诉PHP random_score 包含一个空对象,不是一个数组。要做到这样,我们需要需要指定一个显式空对象:

  1. $params['body'] = array(
  2. 'query' => array(
  3. 'function_score' => array(
  4. 'functions' => array(
  5. array("random_score" => (object) array())
  6. ),
  7. 'query' => array('match_all' => array())
  8. )
  9. )
  10. );
  11. $results = $client->search($params);

现在,JSON会被正常编码,不再会出现解析异常。

扫描/滚动

Elasticsearch的扫描/滚动功能类似于搜索,但在许多方面不同。它的工作方式是使用scan中的search_type执行一个搜索查询。这将启动一个扫描窗口并在扫面时保持打开。这允许真正的一致的分页。
一旦扫描窗口打开,你可能开始在窗口上滚动。这返回的结果要匹配你的查询,但顺序是随机的。这种随机的排序对性能来说是很重要的。深分页时昂贵的,当你需要通过碎片去维护一个分类的一致的排序。

    1. $client = new Elasticsearch\Client();
    2. $params = array(
    3. "search_type" => "scan",    // use search_type=scan
    4. "scroll" => "30s",          // how long between scroll requests. should be small!
    5. "size" => 50,               // how many results *per shard* you want back
    6. "index" => "my_index",
    7. "body" => array(
    8. "query" => array(
    9. "match_all" => array()
    10. )
    11. )
    12. );
    13. $docs = $client->search($params);   // Execute the search
    14. $scroll_id = $docs['_scroll_id'];   // The response will contain no results, just a _scroll_id
    15. // Now we loop until the scroll "cursors" are exhausted
    16. while (\true) {
    17. // Execute a Scroll request
    18. $response = $client->scroll(
    19. array(
    20. "scroll_id" => $scroll_id,  //...using our previously obtained _scroll_id
    21. "scroll" => "30s"           // and the same timeout window
    22. )
    23. );
    24. // Check to see if we got any search hits from the scroll
    25. if (count($response['hits']['hits']) > 0) {
    26. // If yes, Do Work Here
    27. // Get new scroll_id
    28. // Must always refresh your _scroll_id!  It can change sometimes
    29. $scroll_id = $response['_scroll_id'];
    30. } else {
    31. // No results, scroll cursor is empty.  You've exported all the data
    32. break;
    33. }
    34. }

Elasticsearch-PHP 搜索操作的更多相关文章

  1. Elasticsearch 教程--搜索

    搜索 – 基本工具 到目前为止,我们已经学习了Elasticsearch的分布式NOSQL文档存储,我们可以直接把JSON文档扔到Elasticsearch中,然后直接通过ID来进行调取.但是Elas ...

  2. Elasticsearch 数据搜索篇·【入门级干货】

    ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API.本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用.虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的 ...

  3. Elasticsearch分布式搜索集群配置

    配置文件位于%ES_HOME%/config/elasticsearch.yml文件中,用Editplus打开它,你便可以进行配置.   所有的配置都可以使用环境变量,例如:node.rack: ${ ...

  4. ElasticSearch+Kibana 索引操作

    ElasticSearch+Kibana 索引操作 一 前言 ElasticiSearch 简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引 ...

  5. Elasticsearch 数据搜索篇·【入门级干货】===转

    ES即简单又复杂,你可以快速的实现全文检索,又需要了解复杂的REST API.本篇就通过一些简单的搜索命令,帮助你理解ES的相关应用.虽然不能让你理解ES的原理设计,但是可以帮助你理解ES,探寻更多的 ...

  6. elasticsearch的索引操作和文档操作总结

    参考文档:https://es.xiaoleilu.com/010_Intro/00_README.html 一.索引操作 1.查看当前节点的所有的index 查看当前节点的所有的index [roo ...

  7. 使用Logstash同步数据至Elasticsearch,Spring Boot中集成Elasticsearch实现搜索

    安装logstash.同步数据至ElasticSearch 为什么使用logstash来同步,CSDN上有一篇文章简要的分析了以下几种同步工具的优缺点:https://blog.csdn.net/la ...

  8. 十九种Elasticsearch字符串搜索方式终极介绍

    前言 刚开始接触Elasticsearch的时候被Elasticsearch的搜索功能搞得晕头转向,每次想在Kibana里面查询某个字段的时候,查出来的结果经常不是自己想要的,然而又不知道问题出在了哪 ...

  9. Elasticsearch实现搜索推荐词

    本篇介绍的是基于Elasticsearch实现搜索推荐词,其中需要用到Elasticsearch的pinyin插件以及ik分词插件,代码的实现这里提供了java跟C#的版本方便大家参考. 1.实现的结 ...

随机推荐

  1. hessian协议原理

    Hessian 原理分析 一.      远程通讯协议的基本原理 网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络 IO 来实现,其中传输协议比较出名的有 http . t ...

  2. 静态和全局变量的作用域zz

    全局变量和静态变量的存储方式是一样的,只是作用域不同.如果它们未初始化或初始化为0则会存储在BSS段,如果初始化为非0值则会存储在DATA段,见进程的地址空间分配一文. 静态变量的作用域是当前源文件, ...

  3. 从数据库导出数据到excel之List<List<Object>>导出

    说明:有时候数据处理为List<List<Object>>更方便 姊妹篇:从数据库导出数据到excel之List<Map<>>导出 兄弟篇:从数据库导出 ...

  4. Oracle12c之 CDB数据库中数据字典架构

    数据字典就是元数据的集合,比如创建的表,列,约束,触发器等等这些都是元数据,需要保存到数据库中.除此之外,Oracle自身的一些数据库对象,如目录,PL/SQL代码等等这些都是元数据,都需要存放在数据 ...

  5. HDFS(三)

    DataNode 下面的数据文件有两种类型,一种是数据块,一种是数据块的描述文件(元数据文件),后者文件后面带有.meta后缀: Version文件字段内容其实和NameNode里面涵义是一致的: 安 ...

  6. JAVA-Unit03: SQL(基础查询) 、 SQL(关联查询)

    Unit03: SQL(基础查询) . SQL(关联查询) 列别名 当SELECT子句中查询的列是一个函数 或者表达式时,那么查询出来的结果集 中对应的该字段的名字就是这个函数或者 表达式的名字.为此 ...

  7. 1045 access denied for user 'root'@'localhost' using password yes

    mysql -u root -p 方法一:  # /etc/init.d/mysql stop  # mysqld_safe --user=mysql --skip-grant-tables --sk ...

  8. css3实现气泡效果的聊天框

    因为CSS3尚未形成标准,所以现行的浏览器对于css3支持不太一致,某些特性需要加上浏览器前缀 css属性的浏览器前缀 前缀 渲染引擎 使用该引擎的浏览器 -khtml- KHTML Konquero ...

  9. nginx上传文件大小

    采用nginx作反向代理,出现了一个诡异的问题,小文件可以提交,大文件会报500内部错误.这个是什么原因导致的呢? 查wiki可知,上传文件大小相关的有三个配置 client_body_buffer_ ...

  10. 2017百度之星初赛A-1006(HDU-6113)

    思路:在图的外面包一圈'0'字符,然后dfs统计'0'字符的个数和'1'字符的个数.结果如下(num0表示0字符的个数,num1表示1字符的个数): num0 == 1 && num1 ...