PHP中使用ElasticSearch

本文介绍了ES中组合条件查询的强大功能,通过bool语法可拼接复杂条件。还介绍了常用组合查询关键词,如filter、must等。以ES6.5为测试环境,循序渐进展示了添加和搜索功能,包括新建index、定义type、插入数据、取数据等,最后贴出基于Laravel的完整测试代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间:2021-07-16 09:31:12

在es中,使用组合条件查询是其作为搜索引擎检索数据的一个强大之处,在前几篇中,简单演示了es的查询语法,但基本的增删改查功能并不能很好的满足复杂的查询场景,比如说我们期望像mysql那样做到拼接复杂的条件进行查询该如何做呢?es中有一种语法叫bool,通过在bool里面拼接es特定的语法可以做到大部分场景下复杂条件的拼接查询,也叫复合查询

首先简单介绍es中常用的组合查询用到的关键词,

filter:过滤,不参与打分
must:如果有多个条件,这些条件都必须满足 and与
should:如果有多个条件,满足一个或多个即可 or或
must_not:和must相反,必须都不满足条件才可以匹配到 !非

1

2

3

4

5

6

7

{

    "bool": {

        "must": [],--必须满足的条件--and 

        "should": [],--可以满足也可以不满足的条件--or 

        "must_not": []--不能满足的条件--not

    }

}

发生 描述
must
该条款(查询)必须出现在匹配的文件,并将有助于得分。

filter
子句(查询)必须出现在匹配的文档中。然而不像 must查询的分数将被忽略。Filter子句在过滤器上下文中执行,这意味着评分被忽略,子句被考虑用于高速缓存。

should
子句(查询)应该出现在匹配的文档中。如果 bool查询位于查询上下文中并且具有mustor filter子句,则bool即使没有should查询匹配,文档也将匹配该查询 。在这种情况下,这些条款仅用于影响分数。如果bool查询是过滤器上下文 或者两者都不存在,must或者filter至少有一个should查询必须与文档相匹配才能与bool查询匹配。这种行为可以通过设置minimum_should_match参数来显式控制 。

must_not
子句(查询)不能出现在匹配的文档中。子句在过滤器上下文中执行,意味着评分被忽略,子句被考虑用于高速缓存。因为计分被忽略,0所有文件的分数被返回。

网上很多关于ES的例子都过时了,版本很久,这篇文章的测试环境是ES6.5

通过composer 安装

1

composer require 'elasticsearch/elasticsearch'

在代码中引入

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

require 'vendor/autoload.php';

use Elasticsearch\ClientBuilder;

// 配置

$client = ClientBuilder::create()->setHosts(['172.16.55.53'])->build();

// 配置

$client = ClientBuilder::create()->setHosts([

    [

        'host' => 'xxx',

        'port' => '9200',

        'scheme' => 'http',

        'user' => 'xxx',

        'pass' => 'xxxx'

    ],

])->build();

下面循序渐进完成一个简单的添加和搜索的功能。

首先要新建一个 index:

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

1

2

3

4

5

6

7

8

9

10

$params = [

    'index' => 'myindex', #index的名字不能是大写和下划线开头

    'body' => [

        'settings' => [

            'number_of_shards' => 2,

            'number_of_replicas' => 0

        ]

    ]

];

$client->indices()->create($params);

在MySQL里面,光有了数据库还不行,还需要建立表,ES也是一样的,ES中的type对应MySQL里面的表。

注意:ES6以前,一个index有多个type,就像MySQL中一个数据库有多个表一样自然,但是ES6以后,每个index只允许一个type,在往以后的版本中很可能会取消type。

type不是单独定义的,而是和字段一起定义

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

$params = [

    'index' => 'myindex',

    'type' => 'mytype',

    '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'

                ]

            ]

        ]

    ]

];

$client->indices()->putMapping($params);

在定义字段的时候,可以看出每个字段可以定义单独的类型,在first_name中还自定义了 分词器 ik,

这个分词器是一个插件,需要单独安装的,参考另一篇文章:ElasticSearch基本尝试

现在 数据库和表都有了,可以往里面插入数据了

概念:这里的 数据 在ES中叫 文档

1

2

3

4

5

6

7

8

9

10

11

$params = [

    'index' => 'myindex',

    'type' => 'mytype',

    //'id' => 1, #可以手动指定id,也可以不指定随机生成

    'body' => [

        'first_name' => '张',

        'last_name' => '三',

        'age' => 35

    ]

];

$client->index($params);

多插入一点数据,然后来看看怎么把数据取出来:

通过id取出单条数据:

插曲:如果你之前添加文档的时候没有传入id,ES会随机生成一个id,这个时候怎么通过id查?id是多少都不知道啊。

所以这个插入一个简单的搜索,最简单的,一个搜索条件都不要,返回所有index下所有文档:

1

$data $client->search();

现在可以去找一找id了,不过你会发现id可能长这样:zU65WWgBVD80YaV8iVMk,不要惊讶,这是ES随机生成的。

现在可以通过id查找指定文档了:

1

2

3

4

5

6

$params = [

    'index' => 'myindex',

    'type' => 'mytype',

    'id' =>'zU65WWgBVD80YaV8iVMk'

];

$data $client->get($params);

最后一个稍微麻烦点的功能:

注意:这个例子我不打算在此详细解释,看不懂没关系,这篇文章主要的目的是基本用法,并没有涉及到ES的精髓地方,

ES精髓的地方就在于搜索,后面的文章我会继续深入分析

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

$query = [

    'query' => [

        'bool' => [

            'must' => [

                'match' => [

                    'first_name' => '张',

                ]

            ],

            'filter' => [

                'range' => [

                    'age' => ['gt' => 76]

                ]

            ]

        ]

    ]

];

$params = [

    'index' => 'myindex',

//  'index' => 'm*', #index 和 type 是可以模糊匹配的,甚至这两个参数都是可选的

    'type' => 'mytype',

    '_source' => ['first_name','age'], // 请求指定的字段

    'body' => array_merge([

        

PHP使用 ElasticSearch 进行商品搜索的最佳实践如下: 1. 安装 ElasticSearchElasticsearch-PHP 客户端库 要使用 ElasticSearch 进行搜索,首先需要安装 ElasticSearchElasticsearch-PHP 客户端库。可以使用 Composer 来安装 Elasticsearch-PHP 客户端库,例如:composer require elasticsearch/elasticsearch。 2. 创建索引 在 ElasticSearch 中,需要先创建一个索引,然后在该索引中创建一个或多个类型(type),最后将文档(document)添加到类型中。在 PHP 中,可以使用 Elasticsearch-PHP 客户端库来创建索引,例如:$client->indices()->create(['index' => 'my_index'])。 3. 添加文档 在 PHP使用 Elasticsearch-PHP 客户端库,可以使用 $client->index() 方法来添加文档到指定的类型中,例如:$client->index(['index' => 'my_index', 'type' => 'my_type', 'id' => 1, 'body' => ['name' => 'product1', 'price' => 10]])。 4. 进行搜索 在 PHP使用 Elasticsearch-PHP 客户端库进行搜索,可以使用 $client->search() 方法。例如,要搜索名称为“product1”的商品,可以使用以下代码: ``` $params = [ 'index' => 'my_index', 'type' => 'my_type', 'body' => [ 'query' => [ 'match' => [ 'name' => 'product1' ] ] ] ]; $response = $client->search($params); ``` 以上就是在 PHP使用 ElasticSearch 进行商品搜索的最佳实践。当然,还有很多其他的高级搜索技巧,例如使用聚合(aggregation)来计算平均价格、最高价格等等。可以根据具体的需求来逐步深入学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值