Elasticsearch php基本搜索

在前文中,介绍了Elasticsearch-php的一些基本API,链接:PHP Elasticsearch的连接与基本使用。本文将就搜索进行探讨:

一、匹配查询:

        $params = [
            'index' => 'test',
            'type' => 'my_type',
            'body' => [
                'from' => 0, //从第几天开始返回
                'size' => 2, //返回结果数量 limit
                'query' => [
                    'constant_score' => [ //非评分模式执行
                        'filter' => [ 
                            'term' => [ 
                                'name' => 'saki'
                            ]
                        ]
                        
                    ]
                ]
            ]
        ];
       $res = $this->es->search($params);

from-size:从第多少条开始查询n条记录,用于分页,在返回的数据集较大时建议使用scroll。

query:查询语句,与filter的区别在于其会根据_source计算文档的相似度,加之filter会自动缓存结果,故而filter性能更高。

constant_score:不使用检索词的频率对查询结果进行排序。

term 完全匹配(不支持一个term下添加多个条件), 如果需要分词后进行匹配使用 match,下面举例说明两者的区别:

例如有两条记录 “name”:“yukari” ,“name”:“yukari is always 17 years old” 此时的搜索条件是 yukari is,如果在name是'index'=> 'analyzed'的情况下,第二条记录name会被分词为 yukari ,is,always……,match查询会将yukari is分为yukari和is,而且yukari和is只要有一个词以上匹配到,就会返回结果,所以match会返回两条结果。而term则会使用yukari is(yukari is这个查询条件不会被分词)去和原句分词后的结果做匹配,即(yukari,is,always……),没有一个是与yukari is匹配的,所以返回空集。同理,即使用“yukari is always 17 years old”做term搜索,也是空集。故而需要用term做精确搜索时,一定要设置'index'=> 'not_analyzed',即原句不被分词。

二、布尔查询:

        //must = and must_not= not should=or
        $json = '{
            "query" : {
                "bool" : {
                  "should" : [
                    { "term" : { "age" : 19 } },
                    { "term" : { "age" : 17 } }
                  ],
                  "must" : [
                    { "term" : { "name" : "saki" } }
                  ]
                }
            }
        }';
        $params = [
            'index' => 'test',
            'type' => 'my_type',
            'body' => $json,            
        ];

其中must可以理解为and ,must_not理解为not,should理解为or,但需要注意以下几点:

1、在bool查询中,如果存在must或者filter与should在一起的情况,如果should中没有一个匹配,也会返回根据must或者filter匹配的结果。如果只有一个should,那么必须至少匹配should中的一条才会返回结果。所以,一定注意,上例中bool下的should与must不是and关系

2、注意上例的写法与其他查询条件的写法有区别,body使用的是一个json字符串,而不像其他例子一样使用数组。由于布尔运算的包含关系以及php数组对象转json对象的问题,虽然Elasticsearch-php官方API中提供了下面的写法:

'should' => [
       [ 'term' => [ 'age' => 18 ] ],
       [ 'term' => [ 'age' => 19 ] ],
],

请注意‘term’两边多出的“[”符合。但是请一定直接使用json字符串,以避免返回结果与预期不一致!

三、多条件匹配查询,相当于in:

        $params3 = [
            'index' => 'test',
            'type' => 'my_type',
            'body' => [
                'query' => [
                    'constant_score' => [ 
                        'filter' => [ 
                            'terms' => [ 
                                'name' => ['yukari','saki']
                            ]
                        ]
                        
                    ]
                ]
            ]
        ];

四、范围查询,gt >, lt <, gte >=, lte <=:

        $params = [
            'index' => 'test',
            'type' => 'my_type',
            'body' => [
                'query' => [
                    'constant_score' => [
                        'filter' => [ 
                            'range' => [
                                'age' => [
                                    'gt' => 16,
                                    'lt' => 18
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ];

五、基于距离的模糊查询:

        $params = [
            'index' => 'test',
            'type' => 'my_type',
            'body' => [
                'query' => [
                    'fuzzy' => [
                        'name' => [
                            "value" =>"yuki", //模糊的字段
                            "fuzziness" =>    2,
                        ]
                    ]                       

                ]
            ]
        ];
其中,fuzziness是最大的编辑距离,编辑距离即将一个词转换为另一个词的最小操作数,一个修改,插入,删除,都算一个操作。例如上例的结果,可以是yukari(插入两个字符),也可以是saki(修改两个字符)。

六、模糊搜索:
        $params = [
            'index' => 'test',
            'type' => 'my_type',
            'body' => [
                'query' => [
                    'wildcard' => [
                        "name" =>"s*i*",
                    ]                       
                ]
            ]
        ]; 

再次重复一下,在name是'index'=> 'analyzed'的情况下,模糊搜索也是基于分词结果的,例如,正如上面的例子,“yukari”和“yukari is always 17 years old”,y*i可以搜索到两条记录,但是y*o却搜索不到一条记录。

关于搜索,还有许多需要学习总结的地方,待后续继续介绍。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值