php 使用 ElasticSearch 高级查询、过滤、排序

1、下载安装

https://www.elastic.co/guide/en/elasticsearch/client/php-api/7.x/installation.html

2、命令下载文件

composer  require   elasticsearch/elasticsearch="^7.0"

3、官方使用说明文档(权威)

https://www.elastic.co/guide/en/elasticsearch/client/php-api/7.x/connceting.html

实例参考:

# 引入开发包
use Elasticsearch\ClientBuilder;

$client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();

4、创建索引客户端实例参考

https://www.elastic.co/guide/en/elasticsearch/client/php-api/7.x/index_management.html

创建索引实例

$index = [
        "index"=>"lampol",
        "body"=>[
            "mappings"=>[
                "properties"=>[
                    "name"=>[
                        "type"=>"keyword"
                    ],
                    "age"=>[
                        "type"=>"byte"
                    ],
                    "addr"=>[
                        "type"=>"text",
                        "analyzer"=>"ik_max_word"
                    ]
                ]
            ]
        ]
    ];
$response = $client->indices()->create($index);

5、判断索引是否存在、获取mapping数据结构、删除索引index

# 判断索引是否存在
$response = $client->indices()->exists(['index'=>'lampol']);

# 获取mapping数据结构
$response = $client->indices()->getMapping(['index'=>'lampol']);

# 删除索引index
$response = $client->indices()->delete(['index'=>'test1']);

6、文档单个插入

$doc = [
    "index"=>'lampol',
    "id"=>1,
    "body"=>[
        "name"=>"liudehua",
        "age"=>33,
        "addr"=>"中国广东省深圳市"
    ]
];
$response = $client->index($doc);

7、批量插入

$docs['body'] = [
    ['index'=>['_index'=>'lampol','_id'=>2]],
    ['name'=>'liming','age'=>43,'addr'=>'山东省青岛市'],
    ['index'=>['_index'=>'lampol','_id'=>3]],
    ['name'=>'郭富城','age'=>53,'addr'=>'山东省枣庄市']
];
$response = $client->bulk($docs);

8、文档查询修改删除

# 文档查询id=3
$id = ['index'=>'lampol','id'=>3,'_source'=>['name','age'=>33]];
$response = $client->get($id);

# 查询
$param = [
    'index'=>'lampol',
    'body'=>[
        'query'=>[
            'match'=>[
                'addr'=>'深圳'
            ]
        ]
    ]
];
$response = $client->search($param);

# 文档更新id=1
$doc = [
          'index'=>'lampol',
          'id'=>1,
          'body'=>[
              'doc'=>[
                  'age'=>53
              ]
          ]
      ];
$response = $client->update($doc);

# 文档删除id=3
$id = ['index'=>'lampol','id'=>3];
$response = $client->delete($id);

9、ThinkPHP6实战演练

9.1、商品Goods.php搜索
# 引入
use Elasticsearch\ClientBuilder;

class Goods{
  public function search(Request $request) {
    //与es建立连接
    $client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();

    $keywords = $request->param('keywords', '', 'trim');

    $page = $request->param('page');
    $size = 20;
    if ($page) {
        $from = ($page - 1) * 20;
        $pre = $page - 1;
        $next = $page + 1;
    } else {
        $pre = 1;
        $next = 2;
        $from = ($pre - 1) * 20;
    }
    $search = [
        'index' => 'goods',
        'body' => [
            'query' => [
                'match' => [
                    'goods_title' => $keywords
                ]
            ],
            'from' => $from,
            'size' => $size,
            'highlight' => [
                'fields' => [
                    'goods_title' => new \stdClass()
                ],
                'pre_tags' => ["<font style='color:red'>"],
                'post_tags' => ['</font>']
            ]
        ]
    ];
    $res = $client->search($search);
    return view('list', ['goods' => $res['hits']['hits'], 'keywords' => $keywords, 'pre' => $pre, 'next' => $next]);
}
}

9.2、高亮显示

https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/php_json_objects.html

9.3、添加商品到es中

public function save(Request $request){
   $client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();
   $goods_title = $request->param('goods_title');
   $cat_id = 200;
   //插入数据库同时插入es
   $id = Db::name('goods')->insertGetId(['cat_id'=>$cat_id,'goods_title'=>$goods_title]);
   $doc = [
       'index'=>'goods',
       'id'=>$id,
       'body'=>[
           'id'=>$id,
           'goods_title'=>$goods_title
       ]
   ];
   $client->index($doc);
   return view('search');
}

9.4、编辑es中的商品

public function update(Request $request, $id) {
    $goods_title = $request->param('goods_title');
    //1、更新数据库
    Db::name('goods')->where('id', $id)->update(['goods_title' => $goods_title]);
    //2、更新es
    $client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();
    $doc = [
        'index' => 'goods',
        'id' => $id,
        'body' => [
           'doc'=>[
               'goods_title' => $goods_title
           ]
        ]
    ];

    $client->update($doc);
    return view('search');
}

9.5、删除es中的商品

public function delete($id) {
    //1、删除数据库id数据
    Db::name('goods')->where('id', $id)->delete();
    //2、删除es
    $client = ClientBuilder::create()->setHosts(['192.168.1.128:9200'])->build();
    $client->delete(['index' => 'goods', 'id' => $id]);
    return json(['status' => 'success']);
}

一、高级查询

  1. 布尔查询(bool)

bool把各种其它查询通过must(与)、must_not(非)、should(或)的方式进行组合。

GET /yoshop/_search
{
    "query":{
        "bool":{
          "must":     { "match": { "title": "大米" }},
          "must_not": { "match": { "title":  "电视" }},
          "should":   { "match": { "title": "手机" }}
        }
    }
}
  1. 范围查询(range)

range 查询找出那些落在指定区间内的数字或者时间。

GET /heima/_search
{
    "query":{
        "range": {
            "price": {
                "gte":  1000.0,
                "lt":   2800.00
            }
      }
    }
}
  1. 模糊查询(fuzzy)

fuzzy 查询是 term 查询的模糊等价。它允许用户搜索词条与实际词条的拼写出现偏差,但是偏差的编辑距离不得超过2。

GET /youshop/_search
{
    "query": {
      "fuzzy": {
        "title": "applo"
      }
    }
}

上面的查询,也能查询到apple手机

我们可以通过fuzziness来指定允许的编辑距离。

GET /youshop/_search
{
  "query": {
    "fuzzy": {
        "title": {
            "value":"appla",
            "fuzziness":1
        }
    }
  }
}

二、过滤(filter)

filter方式是在查询结果中进行过滤的,不会影响评分。

GET /youshop/_search
{
    "query":{
        "bool":{
          "must":{ "match": { "title": "小米手机" }},
          "filter":{
                "range":{"price":{"gt":3000,"lt":3800.00}}
          }
        }
    }
}

注意:filter中还可以再次进行bool组合条件过滤。

三、排序

  1. 单字段排序

sort 可以让我们按照不同的字段进行排序,并且通过order指定排序的方式。


GET /youshop/_search
{
  "query": {
    "match": {
      "title": "小米手机"
    }
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}
  1. 多字段排序

假定我们想要结合使用 price和_id进行查询,并且匹配的结果首先按照价格排序,然后按照相id排序。

GET /goods/_search
{
    "query":{
        "bool":{
          "must":{ "match": { "title": "小米手机" }},
          "filter":{
                "range":{"price":{"gt":2000,"lt":3000}}
          }
        }
    },
    "sort": [
      { "price": { "order": "desc" }},
      { "_id": { "order": "desc" }}
    ]
}

此处评论已关闭

[player id="719102"/]