IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> php使用es(elasticsearch) 7.x -> 正文阅读

[PHP知识库]php使用es(elasticsearch) 7.x

<?php

require 'vendor/autoload.php';

class MyElasticSearch
{
  private $client;
  // 构造函数
  public function __construct()
  {
    $params = array(
      '127.0.0.1:9200'
    );
    $this->client = ClientBuilder::create()->setHosts($params)->build();
  }

  /**
   * 创建索引
   * */
  public function create_index($index_name) { // 只能创建一次
    $params = [
      'index' => $index_name,  //索引名称
      'body' => [
        'settings' => [ //配置
          'number_of_shards' => 5, // 分片数
          'number_of_replicas' => 0 // 备份数
        ]
      ]
    ];

    try {
      return $this->client->indices()->create($params);
    } catch (\Elasticsearch\Common\Exceptions\BadRequest400Exception $e) {
      $msg = $e->getMessage();
      $msg = json_decode($msg,true);
      return $msg;
    }
  }

  /**
   * 删除索引
   * $index_name 索引名称
   */
  public function delete_index($index_name) {
    $params = ['index' => $index_name];
    try {
      $response = $this->client->indices()->delete($params);

      return ['', $response];
    } catch (\Exception $exception) {
      return ['error',''];
    }
  }

  /**
   * 创建索引
   * properties.type //类型 text、integer、float、double、boolean、date
   */
  public function create_mappings($index_name) {
    $params = [
      'index' => $index_name, //索引名称
      'body' => [
        'properties'=> [  // 配置数据结构与类型
          'name'=> [ // 字段1
            'type'=>'text',
            'index'=> 'true', //是否索引
            'analyzer' => 'ik_max_word' // 分词
          ],
          'age'=> [ // 字段2
            'type'=>'integer',
          ],
          'sex'=> [ // 字段3
            'type'=>'keyword',
            'index'=> 'false',
            ],
          ]
      ],
    ];

    $response = $this->client->indices()->putMapping($params);
    return $response;
  }

  /**
   * 查看映射
   * $index_name 索引名称
   */
  public function get_mapping($index_name) {
    $params = [
      'index' => $index_name,
    ];
    try {
      $response = $this->client->indices()->getMapping($params);
      return ['',$response];
    } catch (\Exception $exception) {
      return ['error',''];
    }
  }

  /**
   * 添加文档
   * $index_name 索引名称
   * $type_name _type 非必填 默认创建
   * $id 非必填 默认创建
   * $doc 添加的内容
   */
  public function add_doc($index_name,$type_name = null,$id,$doc) {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'id' => $id,
      'body' => $doc
    ];

    $response = $this->client->index($params);
    return $response;
  }

  /**
   * 批量创建文档
   * $index_name 索引名称
   * $type_name _type 非必填 默认创建
   * $body 内容
   * $body例:[['create' => [    //index 与 create一致都是创建文档'_id' => $i,],'name' => 'PHPerJiang','age' => 1,'sex' => 2,]];
   */
  public function bulk_create_another($index_name, $type_name = null, $body = [])
  {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'body' => $body,
    ];
    $response = $this->client->bulk($params);
    return $response;
  }

  /**
   * 判断文档存在
   * $index_name 索引名称
   * $type_name _type 非必填 默认创建
   */
  public function exists_doc($index_name,$id,$type_name = null) {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'id' => $id
    ];

    $response = $this->client->exists($params);
    return $response;
  }

  /**
   * 获取文档
   * $index_name 索引名称
   * $type_name _type
   * $id 文档id
   */
  public function get_doc($index_name,$id = null,$type_name = null) {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'id' => $id
    ];
    try {
      $response = $this->client->get($params);
    } catch (\Exception $exception) {
      $response = [];
    }
    return $response;
  }

  /**
   * 一次获取多个文档
   * @param $ids
   * @return array
   */
  public function getDocs($index_name, array $ids, $type_name = null) {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'body' => ['ids' => $ids]
    ];
    return $this->client->mget($params);
  }

  /**
   * 更新文档
   * $type_name _type 
   * $id 文档id 
   * $doc 更新的内容
   */
  public function update_doc($index_name = null,$id = null,$type_name = null, $doc = []) {

    $redisKey = "es_{$index_name}_{$type_name}_$id";
    if ( ! Redis::setNx($redisKey,1) ) {
      return ["error"=>'正在处理'];
    }

    try {
      $params = [
        'index' => $index_name,
        'type' => $type_name,
        'id' => $id,
        'body' => [
          'doc' => $doc
        ]
      ];
      $response = $this->client->update($params);
      return $response;
    } catch (\Exception $exception) {
      throw $exception;
    } finally {
      Redis::del($redisKey);
    }
  }

  /**
   * 批量更新
   * body = [['update' => ['_id' => $i],'doc'=> ['name' => 'PHPerJiang','age'  => 1,'sex'  => 2,]]];
   */
  public function bulk_update_another($index_name, $type = null,$body = []){
    $params = [
      'index' => $index_name,
      'type'  => $type,
      'body'  => $body
    ];
    $response = $this->client->bulk($params);
    return $response;
  }

  /**
   * 删除文档
   * $id 文档id
   */
  public function delete_doc($index_name,$id,$type_name = null) {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'id' => $id
    ];

    $response = $this->client->delete($params);
    return $response;
  }

  /**
   * 批量删除
   * body = [['delete' => ['_id' => $id,]];
   * */
  public function bluk_delete_another($index_name, $type_name = null, $body = []){
    $params = [
      'index' => $index_name,
      'type'  => $type_name,
      'body'  => $body,
    ];

    $response = $this->client->bulk($params);
    return $response;
  }

  /**
   * 查询文档 (分页,排序,权重,过滤)
   * $should = [['should' => [[ 'match' => [ 'name' => ['query' => $keywords,'boost' => 3, // 权重大]]],[ 'match' => [ 'sex' => ['query' => $keywords,'boost' => 2,]]],],]],
   * sort = ['age'=>['order'=>'desc']]
   */
  public function search_doc($index_name,$type_name = null,$search = [], $sort = [],$from = 0, $size = 20) {
    $params = [
      'index' => $index_name,
      'type' => $type_name,
      'body' => [
        'query' => [
          'bool' => $search,
        ],
        'sort' => $sort,
        'from' => $from, 'size' => $size
      ]
    ];

    $results = $this->client->search($params);
    $maxScore  = $results['hits']['max_score'];
    $score = $results['hits']['hits'][0]['_score'];
    $doc   = $results['hits']['hits'][0]['_source'];
    return $results;
  }

}

查询(term、match、bool、filter)区别

一、精准查询term
term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇

1、term单值
字段只有一个值时候,用term关键词查询

查询goods_id值为190的记录

curl -XGET http://127.0.0.1:9200/xyerp/order/_search -H 'Content-Type: application/json' -d '
{
?"query": {
? ? ?"term": {
? ? ? ?"goods_id": "190"
? ? ? }
?}
}


进一步优化查询,因为是精准查询,不需要查询进行评分计算,只希望对文档进行包括或排除的计算,所以我们会使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。推荐如下查询

{ ?
? ? "query" : { ?
? ? ? ? "constant_score" : { ?
? ? ? ? ? ? ?"filter" : { ?
? ? ? ? ? ? ? ? "term" : { ?
? ? ? ? ? ? ? ? ? ? "goods_id" : "190" ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
}'


2、terms多值
字段有一多个值时候,用terms关键词查询,后跟数组

{
? ? "query":{
? ? ? ? "terms":{
? ? ? ? ? ? "goods_id":["190"]
? ? ? ? }
? ? }
}'


?constant_score 以非评分模式查询,推荐如下查询

{ ?
? ? "query" : { ?
? ? ? ? "constant_score" : { ?
? ? ? ? ? ? ?"filter" : { ?
? ? ? ? ? ? ? ? "terms" : { ?
? ? ? ? ? ? ? ? ? ? "goods_id" : ["190","e1909"] ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
}'


3、term多个字段

{
?? ?"query": [{
?? ??? ?"term": {
?? ??? ??? ?"goods_id": "190"
?? ??? ?}
?? ?}, {
?? ??? ?"term": {
?? ??? ??? ?"name": "zhangsan"
?? ??? ?}
?? ?}]
}


?二、匹配查询match
match和term的区别是,match查询的时候,elasticsearch会根据你给定的字段提供合适的分析器,而term查询不会有分析器分析的过程,match查询相当于模糊匹配,只包含其中一部分关键词就行

1、match
进行full text search或者exact value(非string字段或not_analyzed的字段),进行匹配

查询字段merchant_id为2501的值,并按时间倒序

{
? ?"query": {
? ? ?"match": {
? ? ? ?"merchant_id": "2501"
? ? ?}
? ?},
? ?"sort": [
? ? ?{
? ? ? ?"trade_finished_time": {
? ? ? ? ?"order": "desc"
? ? ? ?}
? ? ?}
? ?]
}'


2、match_all
{ "match_all": {}} 匹配所有的, 当不给查询条件时,默认全查。

{
?? ?"query": {
?? ??? ?"match_all": {}
?? ?}
}


3、multi_match
同时对查询的关键词,多个字段同时进行匹配,即多个字段是AND的关系

{
? ? "query":{
? ? ? ? "multi_match":{
? ? ? ? ? ? "query":"2501",
? ? ? ? ? ? "fields":["merchant_id","_id"]
? ? ? ? }
? ? }
}


?同时field还支持更为丰富的查询

在在fields中,按brandName(品牌名)、sortName(分类名)、productName(商品名)productKeyword(商品关键字),搜索“牛仔 弹力”关键词,brandName源值、拼音值、关键字值都是100分,sortName源值、拼音值80分,productName源值60分,productKeyword值20分,分值由高到低优先级搜索

{
? "query": {
? ? "multi_match": {
? ? ? "query": "牛仔 弹力",
? ? ? "fields": [
? ? ? ? "brandName^100",
? ? ? ? "brandName.brandName_pinyin^100",
? ? ? ? "brandName.brandName_keyword^100",
? ? ? ? "sortName^80",
? ? ? ? "sortName.sortName_pinyin^80",
? ? ? ? "productName^60",
? ? ? ? "productKeyword^20"
? ? ? ],
? ? ? "type": <multi-match-type>,
? ? ? "operator": "AND"
? ? }
? }
}


4、match_phrase
?match_phrase查询分析文本,并从分析文本中创建短语查询。
类似 match 查询, match_phrase 查询首先将查询字符串解析成一个词项列表,然后对这些词项进行搜索,但只保留那些包含 全部 搜索词项,且 位置与搜索词项相同的文档

如下,查询 quick brown、quick brown fox、 brown fox可以查询到,quick fox 查询不到

{ ?
? ? ? "query": { ?
? ? ? ? ? "match_phrase": { ?
? ? ? ? ? ? ? "title": "quick brown fox" ?
? ? ? ? ? } ?
? ? ? } ?
} ?


?如下, 查询 a,b,啊和b之间隔3个字符可以查询到,隔不是3个查询不到?

{
? ? "query":{
? ? ? ? "match_phrase" :{
? ? ? ? ? ? "query":"a,b",
? ? ? ? ? ? "slop":3
? ? ? ? }
? ? }
}


三、bool查询
bool查询包含四种操作符,分别是must,should,must_not,query。它们均是一种数组,数组里面是对应的判断条件

must: 必须匹配,与and等价。贡献算分

must_not:必须不匹配,与not等价,常过滤子句用,但不贡献算分

should: 选择性匹配,至少满足一条,与 OR 等价。贡献算分

filter: 过滤子句,必须匹配,但不贡献算分

{ ?
? ? "query" : { ?
? ? ? ? "filtered" : { ?
? ? ? ? ? ? "filter" : { ?
? ? ? ? ? ? ? ? "bool" : { ?
? ? ? ? ? ? ? ? ? ? "should" : [ ?
? ? ? ? ? ? ? ? ? ? ? ? { "term" : {"merchant_id" : 100}}, ?
? ? ? ? ? ? ? ? ? ? ? ? { "term" : {"pay_type" : "3"}} ?
? ? ? ? ? ? ? ? ? ? ], ?
? ? ? ? ? ? ? ? ? ? "must_not" : { ?
? ? ? ? ? ? ? ? ? ? ? ? "term" : {"trade_type" : "2"} ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? } ?
}'


?四、filter查询
过滤器,会查询对结果进行缓存,不会计算相关度,避免计算分值,执行速度非常快。

如下, 查询出status为active的状态

{
? "query": {
? ? "bool": {
? ? ? "filter": {
? ? ? ? "term": {
? ? ? ? ? "status": "active"
? ? ? ? }
? ? ? }
? ? }
? }
}


filter也常和range范围查询一起结合使用,range范围可供组合的选项

gt : 大于

lt : 小于

gte : 大于等于

lte :小于等于

如下,查询merchant_id值为2501下的交易数据

{
? "query": {
? ? "bool": {
? ? ? "must": {
? ? ? ? "term": {
? ? ? ? ? "merchant_id": "2501"
? ? ? ? }
? ? ? },?
? ? ? "filter": {
? ? ? ? "range": {
? ? ? ? ? "trade_finished_time": {
? ? ? ? ? ? "from": "2019-09-01T00:00:00",?
? ? ? ? ? ? "to": "2019-09-30T23:59:59"
? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? }
? }
}


如下查询,must下匹配,filter进行过滤,range定义范围

{ ? ?
? ? "query": { ? ?
? ? ? ? "bool": { ? ?
? ? ? ? ? ? "must": [ ? ?
? ? ? ? ? ? ? ? { ??
? ? ? ? ? ? ? ? ? ? "match": { ??
? ? ? ? ? ? ? ? ? ? ? ? "title": "Search" ??
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? }, ?
? ? ? ? ? ? ? ? { ??
? ? ? ? ? ? ? ? ? ? "match": { ??
? ? ? ? ? ? ? ? ? ? "content": "Elasticsearch" ??
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ], ? ?
? ? ? ? ? ? "filter": [ ?
? ? ? ? ? ? ? ? { ??
? ? ? ? ? ? ? ? ? ? "term": { ??
? ? ? ? ? ? ? ? ? ? ? ? "status": "1" ??
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? }, ?
? ? ? ? ? ? ? ? { ??
? ? ? ? ? ? ? ? ? ? "range": { ??
? ? ? ? ? ? ? ? ? ? ? ? "publish_date": { ??
? ? ? ? ? ? ? ? ? ? ? ? "gte": "2015-01-01" ??
? ? ? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ? ? } ?
? ? ? ? ? ? ] ?
? ? ? ? } ?
? ? ?} ?
} ?


五、常见查询场景
1、查询商户ID为3582,订单号为3601021990030726,按时间范围过滤,按下单时间倒序,每次查询100条

{
?? ?"query": {
?? ??? ?"bool": {
?? ??? ??? ?"must": [{
?? ??? ??? ??? ?"term": {
?? ??? ??? ??? ??? ?"merchant_id": "3582"
?? ??? ??? ??? ?}
?? ??? ??? ?}, {
?? ??? ??? ??? ?"term": {
?? ??? ??? ??? ??? ?"order_num": "3601021990030726"
?? ??? ??? ??? ?}
?? ??? ??? ?}],
?? ??? ??? ?"filter": [{
?? ??? ??? ??? ?"range": {
?? ??? ??? ??? ??? ?"order_time": {
?? ??? ??? ??? ??? ??? ?"from": "2019-11-01T17:00:00+08:00",
?? ??? ??? ??? ??? ??? ?"to": "2019-11-01T20:00:00+08:00"
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}]
?? ??? ?}
?? ?},
?? ?"size": 100,
?? ?"sort": [{
?? ??? ?"order_time": "desc"
?? ?}]
}

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-09 11:30:33  更:2021-09-09 11:30:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:55:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码