php操作ElasticSearch搜索引擎流程详解

目录

〝 古人学问遗无力,少壮功夫老始成 〞

如果这篇文章能给你带来一点帮助,希望给飞兔小哥哥一键三连,表示支持,谢谢各位小伙伴们。

一、安装

通过composer安装

composer require \'elasticsearch/elasticsearch\'

二、使用

创建ES类

<?php
 
require \'vendor/autoload.php\';
 
//如果未设置密码
$es = \\Elasticsearch\\ClientBuilder::create()->setHosts([\'xxx.xxx.xxx.xxx\'])->build();
 
//如果es设置了密码
$es = \\Elasticsearch\\ClientBuilder::create()->setHosts([\'http://username:password@xxx.xxx.xxx.xxx:9200\'])->build()

三、新建ES数据库

index 对应关系型数据(以下简称MySQL)里面的数据库,而不是对应MySQL里面的索引

<?php
$params = [
    \'index\' => \'autofelix_db\', #index的名字不能是大写和下划线开头
    \'body\' => [
        \'settings\' => [
            \'number_of_shards\' => 5,
            \'number_of_replicas\' => 0
        ]
    ]
];
$es->indices()->create($params);

四、创建表

  • 在MySQL里面,光有了数据库还不行,还需要建立表,ES也是一样的
  • ES中的type对应MySQL里面的表
  • ES6以前,一个index有多个type,就像MySQL中一个数据库有多个表一样
  • 但是ES6以后,每个index只允许一个type
  • 在定义字段的时候,可以看出每个字段可以定义单独的类型
  • 在first_name中还自定义了 分词器 ik,这是个插件,是需要单独安装的
<?php
$params = [
    \'index\' => \'autofelix_db\',
    \'type\' => \'autofelix_table\',
    \'body\' => [
        \'mytype\' => [
            \'_source\' => [
                \'enabled\' => true
            ],
            \'properties\' => [
                \'id\' => [
                    \'type\' => \'integer\'
                ],
                \'first_name\' => [
                    \'type\' => \'text\',
                    \'analyzer\' => \'ik_max_word\'
                ],
                \'last_name\' => [
                    \'type\' => \'text\',
                    \'analyzer\' => \'ik_max_word\'
                ],
                \'age\' => [
                    \'type\' => \'integer\'
                ]
            ]
        ]
    ]
];
$es->indices()->putMapping($params);

五、插入数据

  • 现在数据库和表都有了,可以往里面插入数据了
  • 在ES里面的数据叫文档
  • 可以多插入一些数据,等会可以模拟搜索功能
<?php
$params = [
    \'index\' => \'autofelix_db\',
    \'type\' => \'autofelix_table\',
    //\'id\' => 1, #可以手动指定id,也可以不指定随机生成
    \'body\' => [
        \'first_name\' => \'飞\',
        \'last_name\' => \'兔\',
        \'age\' => 26
    ]
];
$es->index($params);

六、 查询所有数据

<?php
$data = $es->search();
 
var_dump($data);

七、查询单条数据

  • 如果你在插入数据的时候指定了id,就可以查询的时候加上id
  • 如果你在插入的时候未指定id,系统将会自动生成id,你可以通过查询所有数据后查看其id
<?php
$params = [
    \'index\' => \'autofelix_db\',
    \'type\' => \'autofelix_table\',
    \'id\' =>  //你插入数据时候的id
];
$data = $es->get($params);

八、搜索

ES精髓的地方就在于搜索

<?php
$params = [
    \'index\' => \'autofelix_db\',
    \'type\' => \'autofelix_table\',
    \'body\' => [
        \'query\' => [
            \'constant_score\' => [ //非评分模式执行
                \'filter\' => [ //过滤器,不会计算相关度,速度快
                    \'term\' => [ //精确查找,不支持多个条件
                        \'first_name\' => \'飞\'
                    ]
                ]
            ]
        ]
    ]
];
 
$data = $es->search($params);
var_dump($data);

九、测试代码

基于Laravel环境,包含删除数据库,删除文档等操作

<?php
use Elasticsearch\\ClientBuilder;
use Faker\\Generator as Faker;
 
/**
 * ES 的 php 实测代码
 */
class EsDemo
{
    private $EsClient = null;
    private $faker = null;
 
    /**
     * 为了简化测试,本测试默认只操作一个Index,一个Type
     */
    private $index = \'autofelix_db\';
    private $type = \'autofelix_table\';
 
    public function __construct(Faker $faker)
    {
        /**
         * 实例化 ES 客户端
         */
        $this->EsClient = ClientBuilder::create()->setHosts([\'xxx.xxx.xxx.xxx\'])->build();
        /**
         * 这是一个数据生成库
         */
        $this->faker = $faker;
    }
 
    /**
     * 批量生成文档
     * @param $num
     */
    public function generateDoc($num = 100) {
        foreach (range(1,$num) as $item) {
            $this->putDoc([
                \'first_name\' => $this->faker->name,
                \'last_name\' => $this->faker->name,
                \'age\' => $this->faker->numberBetween(20,80)
            ]);
        }
    }
 
    /**
     * 删除一个文档
     * @param $id
     * @return array
     */
    public function delDoc($id) {
        $params = [
            \'index\' => $this->index,
            \'type\' => $this->type,
            \'id\' =>$id
        ];
        return $this->EsClient->delete($params);
    }
 
    /**
     * 搜索文档,query是查询条件
     * @param array $query
     * @param int $from
     * @param int $size
     * @return array
     */
    public function search($query = [], $from = 0, $size = 5) {
//        $query = [
//            \'query\' => [
//                \'bool\' => [
//                    \'must\' => [
//                        \'match\' => [
//                            \'first_name\' => \'Cronin\',
//                        ]
//                    ],
//                    \'filter\' => [
//                        \'range\' => [
//                            \'age\' => [\'gt\' => 76]
//                        ]
//                    ]
//                ]
//
//            ]
//        ];
        $params = [
            \'index\' => $this->index,
//            \'index\' => \'m*\', #index 和 type 是可以模糊匹配的,甚至这两个参数都是可选的
            \'type\' => $this->type,
            \'_source\' => [\'first_name\',\'age\'], // 请求指定的字段
            \'body\' => array_merge([
                \'from\' => $from,
                \'size\' => $size
            ],$query)
        ];
        return $this->EsClient->search($params);
    }
 
    /**
     * 一次获取多个文档
     * @param $ids
     * @return array
     */
    public function getDocs($ids) {
        $params = [
            \'index\' => $this->index,
            \'type\' => $this->type,
            \'body\' => [\'ids\' => $ids]
        ];
        return $this->EsClient->mget($params);
    }
 
    /**
     * 获取单个文档
     * @param $id
     * @return array
     */
    public function getDoc($id) {
        $params = [
            \'index\' => $this->index,
            \'type\' => $this->type,
            \'id\' =>$id
        ];
        return $this->EsClient->get($params);
    }
 
    /**
     * 更新一个文档
     * @param $id
     * @return array
     */
    public function updateDoc($id) {
        $params = [
            \'index\' => $this->index,
            \'type\' => $this->type,
            \'id\' =>$id,
            \'body\' => [
                \'doc\' => [
                    \'first_name\' => \'张\',
                    \'last_name\' => \'三\',
                    \'age\' => 99
                ]
            ]
        ];
        return $this->EsClient->update($params);
    }
 
    /**
     * 添加一个文档到 Index 的Type中
     * @param array $body
     * @return void
     */
    public function putDoc($body = []) {
        $params = [
            \'index\' => $this->index,
            \'type\' => $this->type,
            // \'id\' => 1, #可以手动指定id,也可以不指定随机生成
            \'body\' => $body
        ];
        $this->EsClient->index($params);
    }
 
    /**
     * 删除所有的 Index
     */
    public function delAllIndex() {
        $indexList = $this->esStatus()[\'indices\'];
        foreach ($indexList as $item => $index) {
            $this->delIndex();
        }
    }
 
    /**
     * 获取 ES 的状态信息,包括index 列表
     * @return array
     */
    public function esStatus() {
        return $this->EsClient->indices()->stats();
    }
 
    /**
     * 创建一个索引 Index (非关系型数据库里面那个索引,而是关系型数据里面的数据库的意思)
     * @return void
     */
    public function createIndex() {
        $this->delIndex();
        $params = [
            \'index\' => $this->index,
            \'body\' => [
                \'settings\' => [
                    \'number_of_shards\' => 2,
                    \'number_of_replicas\' => 0
                ]
            ]
        ];
        $this->EsClient->indices()->create($params);
    }
 
    /**
     * 检查Index 是否存在
     * @return bool
     */
    public function checkIndexExists() {
        $params = [
            \'index\' => $this->index
        ];
        return $this->EsClient->indices()->exists($params);
    }
 
    /**
     * 删除一个Index
     * @return void
     */
    public function delIndex() {
        $params = [
            \'index\' => $this->index
        ];
        if ($this->checkIndexExists()) {
            $this->EsClient->indices()->delete($params);
        }
    }
 
    /**
     * 获取Index的文档模板信息
     * @return array
     */
    public function getMapping() {
        $params = [
            \'index\' => $this->index
        ];
        return $this->EsClient->indices()->getMapping($params);
    }
 
    /**
     * 创建文档模板
     * @return void
     */
    public function createMapping() {
        $this->createIndex();
        $params = [
            \'index\' => $this->index,
            \'type\' => $this->type,
            \'body\' => [
                $this->type => [
                    \'_source\' => [
                        \'enabled\' => true
                    ],
                    \'properties\' => [
                        \'id\' => [
                            \'type\' => \'integer\'
                        ],
                        \'first_name\' => [
                            \'type\' => \'text\',
                            \'analyzer\' => \'ik_max_word\'
                        ],
                        \'last_name\' => [
                            \'type\' => \'text\',
                            \'analyzer\' => \'ik_max_word\'
                        ],
                        \'age\' => [
                            \'type\' => \'integer\'
                        ]
                    ]
                ]
            ]
        ];
        $this->EsClient->indices()->putMapping($params);
        $this->generateDoc();
    }
}
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容