当前位置: 首页 > 后端技术 > PHP

ElasticSearch结构化搜索和全文搜索

时间:2023-03-30 00:31:49 PHP

1、结构化搜索1.1精确值查找过滤器很重要,因为它们执行速度非常快,不计算相关性(直接跳过整个评分阶段)并且容易缓存。请尽可能使用过滤器查询。术语查询查找我们指定的确切值。术语查询本身很简单。它需要一个字段名称和我们要查找的值:{"term":{"price":20}}通常在查找精确值时我们不想对查询进行评分。我们只想包含或排除文档,所以我们将使用constant_score查询以非评分模式执行术语查询,并使用一个作为统一分数。因为查询的时候不需要计算score,所以使用constant_score的方法会更快。最终的组合结果是一个包含术语查询的constant_score查询:GET/my_store/products/_search{"query":{"constant_score":{"filter":{"term":{"price":20}}}}}1.2组合过滤器1.2.1布尔过滤器{"bool":{"must":[],"should":[],"must_not":[],}}must所有语句必须(必须)匹配,等价和。must_not所有语句不能(mustnot)匹配,相当于NOT。应该至少有一个语句匹配,相当于OR。GET/my_store/products/_search{“query”:{“filtered”:{“filter”:{“bool”:{“should”:[{“term”:{“price”:20}},{“term”":{"productID":"XHDK-A-1293-#fJ3"}}],"must_not":{"term":{"price":30}}}}}}1.2.2封套布尔过滤器SELECTdocumentFROMproductsWHEREproductID="KDKE-B-9947-#kL5"OR(productID="JODL-X-1937-#pV7"ANDprice=30)GET/my_store/products/_search{"query":{"filtered“:{“过滤器”:{“布尔”:{“应该”:[{“术语”:{“产品ID”:“KDKE-B-9947-#kL5”}},{“布尔”:{“必须”:[{“术语”:{“产品ID”:“JODL-X-1937-#pV7”}},{“术语”:{“价格”:30}}]}}]}}}}}1.3查找多个精确值如果我们要查找price字段值为$20或$30的文档怎么办?GET/my_store/products/_search{"query":{"constant_score":{"filter":{"terms":{"price":[20,30]}}}}}1.4rangegt:>大于(大于)lt:<小于(小于)gte:>=大于等于(大于等于)lte:<=小于等于(小于等于)GET/my_store/products/_search{"query":{"constant_score":{"filter":{"range":{"price":{"gte":20,"lt":40}}}}}}如果你想要无限范围(比如说>20),只需省略其中一个约束:"range":{"price":{"gt":20}}daterange"range":{"timestamp":{"gt":"2014-01-0100:00:00","lt":"2014-01-0700:00:00"}}范围查询在与日期字段一起使用时支持日期数学,例如,如果我们想查找在过去一小时内具有时间戳的所有文档:"range":{"timestamp":{"gt":"now-1h"}}"range":{"timestamp":{"gt":"2014-01-0100:00:00","lt":"2014-01-0100:00:00||+1M"}}1.5处理空值1.5.1存在性查询SELECTtagsFROMpostsWHEREtagsISNOTNULLGET/my_index/posts/_search{“query”:{“constant_score”:{“filter”:{“exists”:{“field”:“tags”}}}}}1.5.2。缺少查询SELECTtagsFROMpostsWHEREtagsISNULLGET/my_index/posts/_search{"query":{"constant_score":{"filter":{"missing":{"field":"tags"}}}}}2.完整-文本搜索2.1匹配查询match是核心查询,不管需求如何无论查询什么字段,match查询都应该是首选的查询方式。它是一种高级全文查询,这意味着它可以处理全文和精确字段。匹配查询的主要应用场景是全文搜索。2.1.1.单词查询GET/my_index/my_type/_search{"query":{"match":{"title":"QUICK!"}}}2.1.2多词查询GET/my_index/my_type/_search{"query":{"match":{"title":"BROWNDOG!"}}}匹配具有任意查询词的文档可能会导致一长串不相关的结果。这是一种霰弹枪搜索。也许我们只想搜索包含所有术语的文档,也就是说,我们不匹配brownORdog,而是查找所有匹配brownANDdog的文档。匹配查询也可以接受一个operator运算符作为输入参数,默认是or。我们可以将其更改为并且所有指定的术语都必须匹配:GET/my_index/my_type/_search{"query":{"match":{"title":{"query":"BROWNDOG!","operator":"and"}}}}2.2组合查询GET/my_index/my_type/_search{"query":{"bool":{"must":{"match":{"title":"quick"}},"must_not":{"match":{"title":"lazy"}},"should":[{"match":{"title":"brown"}},{"match":{"title":"dog"}}]}}}2.3控制精度就像我们可以控制匹配查询的精度一样,我们可以通过minimum_should_match参数来控制需要匹配的should语句的个数,可以是绝对数,也可以是它是一个百分比:GET/my_index/my_type/_search{"query":{"bool":{"should":[{"match":{"title":"brown"}},{"match":{"title":"fox"}},{"match":{"title":"dog"}}],"minimum_should_match":2}}}此查询将返回所有标题字段包含"brown"和"fox","brown"AND"dog",或者"fox"AND"dog".如果有一份包含所有三个条件的文件,它将比只包含两个条件的文件更相关。2.4提高查询语句的权重假设我们要查询关于“全文搜索”的文档,但是我们想给提到“Elasticsearch”或“Lucene”的文档更高的权重,更高的权重意味着如果“Elasticsearch”或“Lucene”出现在文档中,它们会比没有这些词的文档获得更高的相关性score_score,即它们在结果集中的出现率更高。GET/_search{"query":{"bool":{"must":{"match":{"content":{"query":"全文搜索","operator":"and"}}},"should":[{"match":{"content":"Elasticsearch"}},{"match":{"content":"Lucene"}}]}}}should语句匹配的越多,相关度越高document的等级越高。到目前为止,一切都很好。但是如果我们想对那些包含Lucene的有更高的权重,而包含Elasticsearch的语句比Lucene的权重更高,怎么处理呢?我们可以通过指定boost来控制任何查询语句的相对权重。boost的默认值为1,大于1会增加一条语句的相对权重。于是将之前的查询改写如下:GET/_search{"query":{"bool":{"must":{"match":{"content":{"query":"fulltextsearch","operator":“和”}}},“应该”:[{“匹配”:{“内容”:{“查询”:“Elasticsearch”,“提升”:3}}},{“匹配”:{“内容”:{"query":"Lucene","boost":2}}}]}}}3、展望网在使用ES的过程中,在网上找了一些ES封装的第三方扩展类,没有找到他们在项目中的第三方扩展类中,进一步封装了在项目中使用起来更加友好的PHP封装类,所以打算自定义一个ES服务类,目前正在开发中,所以熟悉一下文档和总结是第一步,下一步完成后会发布更新。目前的想法是封装一个普通查询操作的方法,支持输入参数查询字段、排序、分页。单独写了一个类似like方法的方法,可以支持搜索词的高亮显示。对于复杂的查询,可以直接支持native方法。附录参考文档地址