连接Elasticsearch

这里采用集群的方式,所以需要启动多个Elasticsearch实例。

$parms = [
    "localhost:1001",
    "localhost:1002",
    "localhost:1003",
];
//连接elasticsearch
$this->client = \Elasticsearch\ClientBuilder::create()->setHosts($parms)->build;

创建索引

$params = [
    'index' => 'user',
    'body' => [
        'settings' => [
            'number_of_shards' => 3,
            'number_of_replicas' => 2
        ]
    ]
]
echo json_encode($this->client->indices()->create($params));

返回结果:

{
  "acknowledged": true,   //索引是否创建成功
  "shards_acknowledged": true,   //分片是否创建成功
  "index": "user"   //索引名称
}

删除索引

$params = [
    'index' => 'user',
];
echo json_encode($this->client->delete($params));

返回结果:

{
  "acknowledged": true   //确认是否删除成功
}

获取文档

$params = [
    'index' => 'user',   //索引名称
    'type' => 'user',   //类型名称
    'id' => '1',
];
echo json_encode($this->client->get($params));

返回结果:

{
  "_index": "user",  //索引名称
  "_type": "user",   //类型名称
  "_id": "1",        //文档id
  "_version": 2,     //版本号
  "_seq_no": 30,     //序列号
  "_primary_term": 1,  //主键
  "found": true,   //是否找到
  "_source": {     //文档内容
    "uid": 1,
    "username": "test",
    "signature": "test",
    "phone": "13276535811",
    "money": "100",
    "address": "天津 天津市 东丽区",
    "create_time": 1652340350
  }
}

修改文档

$params = [
    'index' => 'user',   //索引名称
    'type' => 'user',     //类型名称
    'id' => '1',     //文档id
    'body' => [   //文档内容 
        'uid' => 1,
        'username' => 'test',
        'signature' => 'test',
        'phone' => '13276535811',
        'money' => '100',
        'address' => '天津 天津市 东丽区',
        'create_time' => time(),
    ],
];
echo json_encode($this->client->index($params));

返回结果:

{
  "_index": "user",  //索引名称
  "_type": "user",   //类型名称
  "_id": "1",   //文档id
  "_version": 2,   //版本号
  "result": "updated",   //操作结果
  "_shards": {
    "total": 3,   //分片总数 
    "successful": 3,  //成功数
    "failed": 0  //失败数
  },
  "_seq_no": 30,  //操作序列号
  "_primary_term": 1   //主分片的term
}

搜索文档

  • Match 查询

    $params = [
      'index' => 'user',   //索引名称
      'type' => 'user',   //类型名称
      'body' => [
          'query' => [
              'match' => [
                  'username' => 'test',
              ],
          ],
      ],
    ];
    echo json_encode($this->client->search($params));

    返回结果:

    {
    "took": 23,   //查询耗时
    "timed_out": false,   //是否超时
    "_shards": { //分片信息
      "total": 3,  //分片总数
      "successful": 3,  //成功数
      "skipped": 0,  //跳过数
      "failed": 0  //失败数
    },
    "hits": {   //查询结果
      "total": {   //总数
        "value": 1,  //总数
        "relation": "eq"   //关系
      },
      "max_score": 6.800749,   //最高分
      "hits": [   //结果
        {
          "_index": "user",  //索引名称
          "_type": "user",   //类型名称
          "_id": "1",   //文档id
          "_score": 6.800749,   //分数
          "_source": {   //文档内容
            "uid": 1,
            "username": "test",
            "signature": "test",
            "phone": "13276535811",
            "money": "100",
            "address": "天津 天津市 东丽区",
            "create_time": 1652340350
          }
        }
      ]
    }
    }
  • bool 查询

    $params = [
      'index' => 'user',  //索引名称
      'type' => 'user',  //类型名称
      'body' => [ 
          'query' => [  
              'bool' => [   
                  'must' => [   //查询条件  must表示必须满足(相当于and),should表示可以满足(相当于or)
                      [ 'match' => [ 'username' => '胡' ] ],  
                      [ 'match' => [ 'address' => '云' ] ], 
                  ]
              ]
          ]
      ]
    ];
    echo json_encode($this->client->search($params));

    返回结果:

    {
    "took": 896,
    "timed_out": false,
    "_shards": {
      "total": 3,
      "successful": 3,
      "skipped": 0,
      "failed": 0
    },
    "hits": {
      "total": {
        "value": 1,
        "relation": "eq"
      },
      "max_score": 8.003002,
      "hits": [
        {
          "_index": "user",
          "_type": "user",
          "_id": "305",
          "_score": 8.003002,
          "_source": {
            "uid": 305,
            "username": "李超",
            "phone": "13574552270",
            "signature": "新改思所满确无性口区装农斯更员整图动工织备山象革道转正清系电前自物象很度使今经",
            "money": "15.36",
            "address": "广东省 惠州市 惠阳区",
            "creat_time": "2011-04-15 15:43:49"
          }
        }
      ]
    }
    }
  • 复杂查询

    $params = [
      'index' => 'user',
      'type' => 'user',
      'body' => [
          'query' => [
              'bool' => [
                  'filter' => [   //过滤,返回符合条件的数据
                      'term' => [ 'address' => '云南' ]
                  ],
                  'should' => [
                      'match' => [ 'username' => '李' ]
                  ]
              ]
          ]
      ]
    ];
    echo json_encode($this->client->search($params));
  • Scrolling 查询

    $params = [
      'index' => 'user',
      'type' => 'user',
      'body' => [
          "query" => [
              "match_all" => new \stdClass()
          ],
          'size' => 5   //查询数量
      ]
    ];
    echo json_encode($this->client->search($params));
    while (isset($response['hits']['hits']) && count($response['hits']['hits']) > 0) {  判断是否还有下一页
      $scroll_id = $response['_scroll_id']; //这个是上一次请求返回的scroll_id
      $response = $this->client->scroll([ //这个是滚动查询
              "scroll_id" => $scroll_id,   //上一次请求返回的scroll_id 
              "scroll" => "30s"           //滚动时间
          ]
      );
    }

删除文档

$params = [
    'index' => 'user',   //索引名称
    'type' => 'user',   //类型名称
    'id' => '1',   //文档id
];
echo json_encode($this->client->delete($params));

返回结果:

{
  "_index": "user",   // 索引名称
  "_type": "user",   // 类型名称
  "_id": "1",   // 文档id
  "_version": 3,  // 版本号
  "result": "deleted",  // 操作结果
  "_shards": {   // 分片信息
    "total": 3,   // 分片总数
    "successful": 3,   // 成功数
    "failed": 0   // 失败数
  }, // 分片信息
  "_seq_no": 309,  // 操作序列号
  "_primary_term": 1  // 主分片的term
}

忽略异常

这种会忽略 404 异常

$params = [
    'index' => 'user',   //索引名称
    'type' => 'user',   //类型名称
    'id' => '1',   //文档id
    'client' => [ 'ignore' => 404 ],   //忽略异常
];
echo json_encode($this->client->get($params));

返回结果:

{
  "_index": "user",
  "_type": "user",
  "_id": "1",
  "found": false
}

这里BadRequest400Exception 和 MissingDocument404Exception 都会被忽略:

$params = [
    'index' => 'user',   //索引名称
    'type' => 'user',   //类型名称
    'id' => '1',   //文档id
    'client' => [ 'ignore' => [400, 404] ],   //忽略异常
];
echo json_encode($this->client->get($params));

返回结果:

{
  "_index": "user",
  "_type": "user",
  "_id": "1",
  "found": false
}

返回详细输出

$params = [
    'index' => 'user',   //索引名称
    'type' => 'user',   //类型名称
    'id' => '1',   //文档id
    'client' => [ 'trace' => true ],   //返回详细输出
];
echo json_encode($this->client->get($params));

返回结果:

原来的返回结果是这样的:

{
  "_index": "user",
  "_type": "user",
  "_id": "5",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
    "uid": 5,
    "username": "曾杰",
    "phone": "13215426458",
    "signature": "老和际不日强老理县治件京济划热选影江例事导还开点深际建起厂党方速识来当西住原清处维安价油些",
    "money": "30.37",
    "address": "澳门特别行政区 离岛 -",
    "creat_time": "1996-10-06 18:37:13"
  }
}

但是加了一个trace字段,用于输出详细输出

{
  "transfer_stats": {   //传输统计
    "url": "http://localhost/user/user/5",   //请求url
    "content_type": "application/json; charset=UTF-8",  //请求内容类型
    "http_code": 200,   //请求状态码
    "header_size": 282,  //请求头大小
    "request_size": 163,  //请求体大小
    "filetime": -1,   //文件时间
    "ssl_verify_result": 0,   //ssl验证结果
    "redirect_count": 0,   //重定向次数
    "total_time": 0.001899,   //总时间
    "namelookup_time": 0.000505,   //域名解析时间
    "connect_time": 0.000615,  //连接时间
    "pretransfer_time": 0.000635,   //预传输时间
    "size_upload": 0,   //上传大小
    "size_download": 572,  //下载大小
    "speed_download": 572000,  //下载速度
    "speed_upload": 0,  //上传速度
    "download_content_length": 572,   //下载内容长度
    "upload_content_length": -1,   //上传内容长度
    "starttransfer_time": 0.001882,  //开始传输时间
    "redirect_time": 0,  //重定向时间
    "redirect_url": "",  //重定向url
    "primary_ip": "::1",  //主ip
    "certinfo": [   //证书信息
      
    ],
    "primary_port": 1003,  //主端口
    "local_ip": "::1",  //本地ip
    "local_port": 54994,  //本地端口
    "http_version": 2,  //http版本
    "protocol": 1,  //协议
    "ssl_verifyresult": 0,  //ssl验证结果
    "scheme": "HTTP",  //协议
    "appconnect_time_us": 0, //app连接时间
    "connect_time_us": 615,  //连接时间
    "namelookup_time_us": 505,  //域名解析时间
    "pretransfer_time_us": 635,  //预传输时间
    "redirect_time_us": 0,  //重定向时间
    "starttransfer_time_us": 1882,  //开始传输时间
    "total_time_us": 1899,  //总时间
    "error": "",  //错误信息
    "errno": 0  //错误码 
  },
  "curl": {   //curl信息
    "error": "",  //错误信息
    "errno": 0 //错误码
  },
  "effective_url": "http://localhost/user/user/5",  //有效url
  "headers": {  //请求头
    "Warning": [  //警告
      "299 Elasticsearch-7.8.0-757314695644ea9a1dc2fecd26d1a43856725e65 \"[types removal] Specifying types in document get requests is deprecated, use the /{index}/_doc/{id} endpoint instead.\""   //警告信息
    ],
    "content-type": [   //内容类型
      "application/json; charset=UTF-8"   //内容类型
    ],   
    "content-length": [   //内容长度
      "572"  //内容长度
    ]
  },
  "version": "1.1", //版本
  "status": 200,  //状态码
  "reason": "OK",  //状态码说明
  "body": {   //返回内容
    "_index": "user", //索引
    "_type": "user",   //类型
    "_id": "5",   //id
    "_version": 1,  //版本
    "_seq_no": 0,  //序列号
    "_primary_term": 1,  //主键
    "found": true,  //是否找到
    "_source": {   //内容
      "uid": 5,
      "username": "曾杰",
      "phone": "13215426458",
      "signature": "老和际不日强老理县治件京济划热选影江例事导还开点深际建起厂党方速识来当西住原清处维安价油些",
      "money": "30.37",
      "address": "澳门特别行政区 离岛 -",
      "creat_time": "1996-10-06 18:37:13"
    }
  }
}

PHP 处理 JSON 数组或对象

  • 空对象

    {
      "query" : {
          "match" : {
              "content" : "quick brown fox"
          }
      },
      "highlight" : {
          "fields" : {
              "content" : {}   //这个空对象便会引起问题, 因为这个空对象会被转换成一个字符串, 并且会被解析成一个数组, 因此会出现问题
          }
      }
    }

    改变为:

    $params['body'] = array(
      'query' => array(
          'match' => array(
              'username' => '默然'
          )
      ),
      'highlight' => array(
          'fields' => array(
              'content' => new \stdClass()   //使用PHP stdClass类来代替空对象, 因为这个类不会被转换成字符串, 并且不会被解析成数组, 因此不会出现问题
          )
      )
    );
    $results = $this->client->search($params);

修改文档

  • 部分修改

    $params = [
      'index' => 'user',
      'type' => 'user',
      'id' => '3',
      'body' => [
          'doc' => [
              'username' => 'ab313131313c',
              'money' => '100',
          ]
      ]
    ];
    $response = $this->client->update($params);
    echo json_encode($response);     

    返回结果:

    {
    "_index": "user",
    "_type": "user",
    "_id": "3",
    "_version": 3,
    "result": "updated",
    "_shards": {
      "total": 3,
      "successful": 3,
      "failed": 0
    },
    "_seq_no": 369,
    "_primary_term": 1
    }
最后修改:2022 年 05 月 12 日
如果觉得我的文章对你有用,请随意赞赏