热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

分布式搜索引擎02

分布式搜索引擎02 在昨天的学习中,我们已经导入了大量数据到elasticsearch中,实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜

分布式搜索引擎02

 

在昨天的学习中,我们已经导入了大量数据到elasticsearch中,实现了elasticsearch的数据存储功能。但elasticsearch最擅长的还是搜索和数据分析。

所以今天,我们研究下elasticsearch的数据搜索功能。我们会分别使用DSLRestClient实现搜索。

 


1.DSL查询文档

elasticsearch的查询依然是基于JSON风格的DSL来实现的。


1.1.DSL查询分类

Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括:



  • 查询所有:查询出所有数据,一般测试用。例如:match_all



  • 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引库中匹配。例如:



    • match_query



    • multi_match_query





  • 精确查询:根据精确词条值查找数据,一般是查找keyword、数值、日期、boolean等类型字段。例如:



    • range



    • term





  • 地理(geo)查询:根据经纬度查询。例如:



    • geo_distance



    • geo_bounding_box





  • 复合(compound)查询:复合查询可以将上述各种查询条件组合起来,合并查询条件。例如:



    • bool



    • function_score





 

查询的语法基本一致,我们以查询所有为例,其中:查询类型为match_all,没有查询条件

# 查询所有
GET
/hotel/_search
{
"query": {
"match_all": { }
}
}

其它查询无非就是查询类型查询条件的变化。

 


1.2.全文检索查询


1.2.1.使用场景

全文检索查询的基本流程如下:



  • 对用户搜索的内容做分词,得到词条



  • 根据词条去倒排索引库中匹配,得到文档id



  • 根据文档id找到文档,返回给用户



比较常用的场景包括:



  • 商城的输入框搜索



  • 百度输入框搜索



例如京东:

因为是拿着词条去匹配,因此参与搜索的字段也必须是可分词的text类型的字段。

 


1.2.2.基本语法

常见的全文检索查询包括:



  • match查询:单字段查询



  • multi_match查询:多字段查询,任意一个字段符合条件就算符合查询条件



# match查询
GET 
/hotel/_search
{
  
"query": {
    
"match": {
      
"all""如家外滩"
    }
  }
}
# mulit_match查询
GET 
/hotel/_search
{
  
"query": {
    
"multi_match": {
      
"query""如家外滩",
      
"fields": ["name"" brand", "business"]
    }
  }
}

match查询示例:

multi_match查询示例:

可以看到,两种查询结果是一样的,为什么?

因为我们将brand、name、business值都利用copy_to复制到了all字段中。因此你根据三个字段搜索,和根据all字段搜索效果当然一样了。

但是,搜索字段越多,对查询性能影响越大,因此建议采用copy_to,然后单字段查询的方式。


1.2.4.总结

match和multi_match的区别是什么?



  • match:根据一个字段查询



  • multi_match:根据多个字段查询,参与查询字段越多,查询性能越差



 


1.3.精准查询

精确查询一般是查找keyword、数值、日期、boolean等类型字段。所以不会对搜索条件分词。常见的有:



  • term:根据词条精确值查询



  • range:根据值的范围查询




1.3.1.term查询

因为精确查询的字段搜是不分词的字段,因此查询的条件也必须是不分词的词条。查询时,用户输入的内容跟自动值完全匹配时才认为符合条件。如果用户输入的内容过多,反而搜索不到数据。

示例:

# term查询
GET
/hotel/_search
{
"query": {
"term": {
"city": "上海"
}
}
}

当我搜索的是精确词条时,能正确查询出结果:

 但是,当我搜索的内容不是词条,而是多个词语形成的短语时,反而搜索不到:


 


1.3.2.range查询

范围查询,一般应用在对数值类型做范围过滤的时候。比如做价格范围过滤。

示例:

# range查询
GET
/hotel/_search
{
"query": {
"range": {
"price": {
"gte": 500,
"lte": 1000
}
}
}
}

 


1.3.3.总结

精确查询常见的有哪些?



  • term查询:根据词条精确匹配,一般搜索keyword类型、数值类型、布尔类型、日期类型字段



  • range查询:根据数值范围查询,可以是数值、日期的范围



 


1.4.地理坐标查询

所谓的地理坐标查询,其实就是根据经纬度查询

官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-queries.html

 

常见的使用场景包括:



  • 携程:搜索我附近的酒店



  • 滴滴:搜索我附近的出租车



  • 微信:搜索我附近的人



附近的酒店:

 

 

附近的车:


1.4.1.矩形范围查询

矩形范围查询,也就是geo_bounding_box查询,查询坐标落在某个矩形范围的所有文档。

 

查询时,需要指定矩形的左上右下两个点的坐标,然后画出一个矩形,落在该矩形内的都是符合条件的点。

语法如下:

# geo_bounding_box查询
GET
/hotel/_search
{
"query": {
"geo_bounding_box": {
"location": {
"top_left": {
"lat": 31.1,
"lon": 121.5
},
"bottom_right": {
"lat": 30.9,
"lon": 121.7
}
}
}
}
}

这种并不符合“附近的人”这样的需求,所以我们就不做了。

 


1.4.2.附近查询

附近查询,也叫做距离查询(geo_distance):查询到指定中心点小于某个距离值的所有文档。

 

换句话来说,在地图上找一个点作为圆心,以指定距离为半径,画一个圆,落在圆内的坐标都算符合条件:

 

示例:

我们先搜索陆家嘴附近15km的酒店

# geo_distance 查询,distance半径,location圆心
GET
/hotel/_search
{
"query": {
"geo_distance": {
"distance": "15km",
"location": "31.21, 121.5"
}
}
}

发现共有47家酒店。

 

然后把半径缩短到3公里:

可以发现,搜索到的酒店数量减少到了5家。

 


1.5.复合查询

复合(compound)查询:复合查询可以将其它简单查询组合起来,实现更复杂的搜索逻辑。常见的有两种:



  • fuction score:算分函数查询,可以控制文档相关性算分,控制文档排名



  • bool query:布尔查询,利用逻辑关系组合多个其它的查询,实现复杂搜索



 


1.5.1.相关性算分

当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。

例如,我们搜索 "虹桥如家",结果如下:

[
{
"_score": 17.850193,
"_source": {
"name": "虹桥如家酒店真不错",
}
},
{
"_score": 12.259849,
"_source": {
"name": "外滩如家酒店真不错",
}
},
{
"_score": 11.91091,
"_source": {
"name": "迪士尼如家酒店真不错",
}
}
]

在elasticsearch中,早期使用的打分算法是TF-IDF算法,公式如下:

 

在后来的5.1版本升级中,elasticsearch将算法改进为BM25算法,公式如下

 

 

 

 

 



推荐阅读
  • 全面解析运维监控:白盒与黑盒监控及四大黄金指标
    本文深入探讨了白盒和黑盒监控的概念,以及它们在系统监控中的应用。通过详细分析基础监控和业务监控的不同采集方法,结合四个黄金指标的解读,帮助读者更好地理解和实施有效的监控策略。 ... [详细]
  • Spring Cloud因其强大的功能和灵活性,被誉为开发分布式系统的‘一站式’解决方案。它不仅简化了分布式系统中的常见模式实现,还被广泛应用于企业级生产环境中。本书内容详实,覆盖了从微服务基础到Spring Cloud的高级应用,适合各层次的开发者。 ... [详细]
  • SpringCloud电商平台开发指南:实战案例解析
    本文详细介绍了基于SpringCloud构建的电商平台项目,涵盖了从技术选型到项目部署的全流程,旨在帮助开发者快速掌握电商平台的开发技巧。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 随着网络安全威胁的不断演变,电子邮件系统成为攻击者频繁利用的目标。本文详细探讨了电子邮件系统中的常见漏洞及其潜在风险,并提供了专业的防护建议。 ... [详细]
  • 本文探讨了如何在日常工作中通过优化效率和深入研究核心技术,将技术和知识转化为实际收益。文章结合个人经验,分享了提高工作效率、掌握高价值技能以及选择合适工作环境的方法,帮助读者更好地实现技术变现。 ... [详细]
  • 本文探讨了2012年4月期间,淘宝在技术架构上的关键数据和发展历程。涵盖了从早期PHP到Java的转型,以及在分布式计算、存储和网络流量管理方面的创新。 ... [详细]
  • 云计算的优势与应用场景
    本文详细探讨了云计算为企业和个人带来的多种优势,包括成本节约、安全性提升、灵活性增强等。同时介绍了云计算的五大核心特点,并结合实际案例进行分析。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • ZooKeeper集群脑裂问题及其解决方案
    本文深入探讨了ZooKeeper集群中可能出现的脑裂问题,分析其成因,并提供了多种有效的解决方案,确保集群在高可用性环境下的稳定运行。 ... [详细]
  • Java项目分层架构设计与实践
    本文探讨了Java项目中应用分层的最佳实践,不仅介绍了常见的三层架构(Controller、Service、DAO),还深入分析了各层的职责划分及优化建议。通过合理的分层设计,可以提高代码的可维护性、扩展性和团队协作效率。 ... [详细]
  • 从码农到创业者:我的职业转型之路
    在观察了众多同行的职业发展后,我决定分享自己的故事。本文探讨了为什么大多数程序员难以成为架构师,并阐述了我从一家外企离职后投身创业的心路历程。 ... [详细]
  • 本题通过将每个矩形视为一个节点,根据其相对位置构建拓扑图,并利用深度优先搜索(DFS)或状态压缩动态规划(DP)求解最小涂色次数。本文详细解析了该问题的建模思路与算法实现。 ... [详细]
  • 本文介绍了 Elasticsearch 中常见的字段数据类型,包括文本、数值、日期、布尔值、二进制、范围、复杂对象和地理位置等类型,并详细说明了它们的应用场景和特点。 ... [详细]
author-avatar
飞翔的10号
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有