首先使用composer安装elasticsearch composer require elasticsearch/elasticsearch
简单封装ES类, 需要注意es7下取消了type
<?php
namespace app\common\lib;
use Elasticsearch\ClientBuilder;
class Es
{
private $client;
// 构造函数
public function __construct()
{
$params = array(
'127.0.0.1:9200'
);
$this->client = ClientBuilder::create()->setHosts($params)->build();
}
public function getClient() {
return $this->client;
}
// 创建索引
public function create_index($index_name = 'meitian', $properties = []) {
$params = [
'index' => $index_name
];
$exists = $this->client->indices()->exists($params);
if(!$exists) {
$params['body']['settings']['number_of_shards'] = 5;
$params['body']['settings']['number_of_replicas'] = 0;
if(!empty($properties)) {
$params['body']['mappings'] = [
'_source' => [
'enabled' => true
],
'properties' => $properties
];
}
echo 'create index: '.$index_name;
$response = $this->client->indices()->create($params);
return $response;
}
}
// 删除索引
public function delete_index($index_name = 'meitian') {
$params = [
'index' => $index_name
];
$response = $this->client->indices()->delete($params);
return $response;
}
// 添加文档
public function add_doc($id, $doc, $index_name = 'meitian') {
$params = [
'index' => $index_name,
'id' => $id,
'body' => $doc
];
$response = $this->client->index($params);
return $response;
}
// 批量添加文档
public function bulk_doc($docs, $index_name = 'meitian') {
$params = ['body' => []];
$res = 0;
foreach ($docs as $i => $item) {
if(!isset($item['id']) || empty($item['id'])) {
continue;
}
$params['body'][] = [
'index' => [
'_index' => $index_name,
'_id' => $item['id']
],
];
unset($item['id']);
$params['body'][] = $item;
if ($i % 1000 == 0) {
$responses = $this->client->bulk($params);
$params = ['body' => []];
unset($responses);
}
$res++;
}
if (!empty($params['body'])) {
$responses = $this->client->bulk($params);
}
return $res;
}
// 判断文档存在
public function exists_doc($id, $index_name = 'meitian') {
$params = [
'index' => $index_name,
'id' => $id
];
$response = $this->client->exists($params);
return $response;
}
// 获取文档
public function get_doc($id, $index_name = 'meitian') {
$params = [
'index' => $index_name,
'id' => $id
];
$response = $this->client->get($params);
return $response;
}
// 更新文档
public function update_doc($id, $doc, $index_name = 'meitian') {
$params = [
'index' => $index_name,
'id' => $id,
'body' => [
'doc' => $doc
]
];
$response = $this->client->update($params);
return $response;
}
// 删除文档
public function delete_doc($id, $index_name = 'meitian') {
$params = [
'index' => $index_name,
'id' => $id
];
$response = $this->client->delete($params);
return $response;
}
//查看映射
public function get_mapping($index_name = "meitian") {
$params = [
'index' => $index_name,
];
$response = $this->client->indices()->getMapping($params);
return $response;
}
}
创建索引
//实例化ES
$es = new Es();
//创建索引 字段根据实际情况来
$properties = [
'user_id' => [
'type' => 'integer',
],
'name' => [
//注意这里用了ik进行了中文分词 文档https://github.com/medcl/elasticsearch-analysis-ik
"type" => "text",
"analyzer" => "ik_max_word",
"search_analyzer" => "ik_smart"
],
'location' => [
'type' => 'geo_point' //地理坐标
]
];
$res = $es->create_index('store', $properties);
添加文档
//添加门店数据
$stores = StoreModel::getAll('id, user_id, name, point_lng, point_lat', []);
foreach ($stores as $i => &$item) {
$item['location'] = [
'lat' => $item['point_lat'],
'lon' => $item['point_lng']
];
unset($item['point_lat']);
unset($item['point_lng']);
}
$res = $es->bulk_doc($stores, 'store');
搜索文档
$must = [];
if(!empty($user_id)) {
$must[] = ['term' => ['user_id' => $user_id]];
}
if(!empty($name)) {
$must[] = ['match' => ['name' => $name]];
}
$params = [
'index' => 'store',
'from' => 0,
'size' => 200, //取200个
'body' => [
'query' => [
'bool' => [
'must' => $must, //额外筛选条件
'filter' => [
'geo_distance' => [
'distance' => '50km', //附近50km范围内
'location' => [
'lat' => $lat,
'lon' => $lng
]
]
]
]
],
'sort' => [
'_geo_distance' => [ //按照距离由近到远排序
"unit" => "km",
"order" => "asc",
"location" => [
'lat' => $lat,
'lon' => $lng
],
"mode" => "min"
]
]
]
];
//实例化Elasticsearch
$es = new Es();
//搜索
$retDoc = $es->getClient()->search($params);