首页 > 技术文章 > ElasticSearch基本操作

ccdr 2021-08-25 10:59 原文

ElasticSearch

在laravel中安装

composer require elasticsearch/elasticsearch

创建索引

类似于创建数据库,创建的时候只需要指定索引名称就可以了,同时需要使用indices()

//创建es对象
$client = ClientBuilder::create()->setHosts(config('es.host'))->build();
//设置参数(索引名称=数据库)
$params = [
    'index'=>'house_index'
];
//创建索引
return $client->indices()->create($params);

给索引添加文档

类似于给某个数据库下的某张数据表添加内容

  • index类似于库名
  • type类似于表名
  • id类似于数据的主键id
  • body类似于主键id对应的内容
//创建es对象
$client = ClientBuilder::create()->setHosts(config('es.host'))->build();
$params = [
    'index'=>'house_index',//类似于选择给哪个数据库添加
    'type'=>'house',//类似于选择给哪张数据表添加
    'id'=>1,//类似于给某条数据指定了主键id
    'body'=>[
        'h_name'=>'某某小区',
        'h_money'=>2000
    ]//类似于某个主键id对应的数据
];

//添加
$res = $client->index($params);
dd($res);

修改索引的文档

相当于在某个数据库下的某张数据表中,根据id修改某个文档的内容

注意:因为是修改文档的内容,所以body增加了下标doc

$client = ClientBuilder::create()->setHosts(config('es.host'))->build();
$params = [
    //在某个数据库下的某张数据表中,根据id修改某个文档的内容
    'index'=>'house_index',
    'type'=>'house',
    'id'=>1,
    'body'=>[
        //因为修改的是文档内容,所以需要指定下标为doc
        'doc'=>['h_money'=>3000]
    ]
];
dd($client->update($params));

删除索引的文档

类似于根据id删除某个数据库下的某张数据表的信息

$client = ClientBuilder::create()->setHosts(config('es.host'))->build();
$params = [
    //在某个数据库下的某张数据表中,根据id修改某个文档的内容
    'index'=>'house_index',
    'type'=>'house',
    'id'=>1
];
dd($client->delete($params));

中文分词器

主要适用于关键字搜索的时候,用来提高查询效率的。其中number_of_shards 每个索引的主分片数,默认值是5。这个配置在索引创建后不能修改。number_of_replicas每个主分片的副本数,默认值是1。对于活动的索引库,这个配置可以随时修改

Elasticsearch里面有2份内容,一份是原始文档,也就是_source字段里的内容,我们在Elasticsearch中搜索文档,查看的文档内容就是_source中的内容;另一份是倒排索引,倒排索引中的数据结构是倒排记录表,记录了词项和文档之间的对应关系

analyzed:字段被索引,会做分词,可搜索。反过来,如果需要根据某个字段进搜索,index属性就应该设置为analyzed

//生成es对象
$es = ClientBuilder::create()->setHosts(config('es.host'))->build();
//配置参数
$params = [
    //在哪个库下面进行内容的配置
    'index'=>'users_index',
    'body'=>[
        'settings'=>[
            'number_of_shards'=>5,//主分片数(分区)
            'number_of_replicas'=>2//副本
        ],
        'mappings'=>[
            //_source表示原文检索
            '_source'=>[
                'enabled'=>true
            ],
            //检索的字段
            'properties'=>[
                //字段名称
                'truename'=>[
                    'type'=>'text',//类型
                    'analyzer' => 'ik_max_word',//分词器
                    'search_analyzer' => 'ik_max_word'//分词器
                ]
            ]
        ]
    ]
];
//创建索引
dd($es->indices()->create($params));

批量给索引中添加数据

$data = User::all()->toArray();
//创建es对象
$client = ClientBuilder::create()->setHosts(config('es.host'))->build();
foreach ($data as $k=>$v){
    $params = [
        'index'=>'users_index',//类似于选择给哪个数据库添加
        'type'=>'_doc', //当添加类型比较多时,值应该设置为_doc
        'id'=>$v['id'],//类似于给某条数据指定了主键id
        'body'=>$v//类似于某个主键id对应的数据
    ];
    $client->index($params);
}

普通检索(不考虑分页的情况)

$word = $request['word'];
if(empty($word)){
    return ['code'=>1,'msg'=>'不能为空','data'=>null];
}

$client = ClientBuilder::create()->setHosts(config('es.host'))->build();//创建es实例
//设置查询的条件
$params = [
    'index' => 'users_index',//索引(类似于库)
    'type' => '_doc',
    'body' => [
        //查询内容
        'query' => [
            'match' => [//匹配
                'truename' => $word//匹配字段
            ]
        ]
    ]
];

$res = $client->search($params);
print_r($res);

分页检索

$word = input('word');//接收关键字
$page = input('page',1);//接收当前页(如果没接收到,默认是1)
$size = 5;//每页显示条数
$limit = ($page-1)*$size;//偏移量
$client = ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();//创建es实例
//设置查询的条件
$params = [
    'index' => 'goodslists_index',//索引(类似于库)
    'type' => '_doc',//根据需要决定写不写
    'body' => [
        //查询内容
        'query' => [
            'match' => [//匹配
                'goods_name' => $word//匹配字段
            ]
        ],
        'highlight' => [//高亮
            'pre_tags' => ["<em style='color: red'>"],//样式自己写
            'post_tags' => ["</em>"],
            'fields' => [
                "goods_name" => new \stdClass()
            ]
        ]
    ]
];
//分页限制(可以直接写在$params里面)
$params["size"] = $size;//每页显示条数
$params["from"] = $limit;//偏移量
$results = $client->search($params);//es搜索
foreach ($results['hits']['hits'] as $k=>$v){
    $results['hits']['hits'][$k]['_source']['goods_name'] = $v['highlight']['goods_name'][0];
}

$data = array_column($results['hits']['hits'],'_source');

$arr['data'] = $data;//数据
$arr['page'] = $page;//当前页
$arr['total'] = $results['hits']['total']['value'];//总条数
$arr['last_page'] = ceil($results['hits']['total']['value']/$size);//总页数

print_r($arr);//剩下的就是前端展示的事情了

推荐阅读