什么是全文搜索?
百度百科中的定义:
全文搜索引擎是目前广泛应用的主流搜索引擎。它的工作原理是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
从定义中我们已经可以大致了解全文检索的思路了,为了更详细的说明,我们先从生活中的数据说起。
我们生活中的数据总体分为两种:结构化数据 和 非结构化数据。
- 结构化数据: 指具有固定格式或有限长度的数据,如数据库,元数据等。
- 非结构化数据: 非结构化数据又可称为全文数据,指不定长或无固定格式的数据,如邮件,word 文档等。
当然有的地方还会有第三种:半结构化数据,如 XML,HTML 等,当根据需要可按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。
根据两种数据分类,搜索也相应的分为两种:结构化数据搜索 和 非结构化数据搜索。
对于结构化数据,我们一般都是可以通过关系型数据库 (mysql,oracle 等) 的 table 的方式存储和搜索,也可以建立索引。
对于非结构化数据,也即对全文数据的搜索主要有两种方法:顺序扫描法,全文检索。
顺序扫描
通过文字名称也可了解到它的大概搜索方式,即按照顺序扫描的方式查询特定的关键字。
例如给你一张报纸,让你找到该报纸中“RNG”的文字在哪些地方出现过。你肯定需要从头到尾把报纸阅读扫描一遍然后标记出关键字在哪些版块出现过以及它的出现位置。
这种方式无疑是最耗时的最低效的,如果报纸排版字体小,而且版块较多甚至有多份报纸,等你扫描完你的眼睛也差不多了。
全文搜索
对非结构化数据顺序扫描很慢,我们是否可以进行优化?把我们的非结构化数据想办法弄得有一定结构不就行了吗?将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这种方式就构成了全文检索的基本思路。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
还以读报纸为例,我们想关注最近英雄联盟 S8 全球总决赛的新闻,假如都是 RNG 的粉丝,如何快速找到 RNG 新闻的报纸和版块呢?全文搜索的方式就是,将所有报纸中所有版块中关键字进行提取,如 "EDG”,“RNG”,“FW”,“战队”,“英雄联盟" 等。然后对这些关键字建立索引,通过索引我们就可以对应到该关键词出现的报纸和版块。注意区别 目录搜索引擎。
为什么要用全文搜索搜索引擎
我们的所有数据在数据库里面都有,而且 MySQL、PG 等数据库里也能提供查询检索或者聚类分析功能,直接通过数据库查询不就可以了吗?
确实,我们大部分的查询功能都可以通过数据库查询获得,如果查询效率低下,还可以通过建数据库索引,优化 SQL 等方式进行提升效率,甚至通过引入缓存来加快数据的返回速度。如果数据量更大,就可以分库分表来分担查询压力。
那为什么还要全文搜索引擎呢?我们主要从以下几个原因分析:
数据类型
全文索引搜索支持非结构化数据的搜索,可以更好地快速搜索大量存在的任何单词或单词组的非结构化文本。
例如 Google,百度类的网站搜索,它们都是根据网页中的关键字生成索引,我们在搜索的时候输入关键字,它们会将该关键字即索引匹配到的所有网页返回;还有常见的项目中应用日志的搜索等等。对于这些非结构化的数据文本,关系型数据库搜索不是能很好的支持。
索引的维护
一般传统数据库,全文检索都实现的很鸡肋,因为一般也没人用数据库存文本字段。进行全文检索需要扫描整个表,如果数据量大的话即使对 SQL 的语法优化,也收效甚微。建立了索引,但是维护起来也很麻烦,对于 insert 和 update 操作都会重新构建索引。
什么时候使用全文搜索引擎:
- 搜索的数据对象是大量的非结构化的文本数据。
- 文件记录量达到数十万或数百万个甚至更多。
- 支持大量基于交互式文本的查询。
- 需求非常灵活的全文搜索查询。
- 对高度相关的搜索结果的有特殊需求,但是没有可用的关系数据库可以满足。
- 对不同记录类型、非文本数据操作或安全事务处理的需求相对较少的情况。
Lucene,Solr, ElasticSearch ?
现在主流的搜索引擎大概就是:Lucene,Solr,ElasticSearch。
它们的索引建立都是根据倒排索引的方式生成索引,何谓倒排索引?
维基百科
倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。
Lucene
Lucene 是一个 Java 全文搜索引擎,完全用 Java 编写。Lucene 不是一个完整的应用程序,而是一个代码库和 API,可以很容易地用于向应用程序添加搜索功能。
Lucene 通过简单的 API 提供强大的功能:
可扩展的高性能索引
- 在现代硬件上超过 150GB / 小时
- 小 RAM 要求 - 只有 1MB 堆
- 增量索引与批量索引一样快
- 索引大小约为索引文本大小的 20-30%
强大,准确,高效的搜索算法
- 排名搜索 - 首先返回最佳结果
- 许多强大的查询类型:短语查询,通配符查询,邻近查询,范围查询等
- 现场搜索(例如标题,作者,内容)
- 按任何字段排序
- 使用合并结果进行多索引搜索
- 允许同时更新和搜索
- 灵活的分面,突出显示,连接和结果分组
- 快速,内存效率和错误容忍的建议
- 可插拔排名模型,包括矢量空间模型和 Okapi BM25
- 可配置存储引擎(编解码器)
跨平台解决方案
- 作为 Apache 许可下的开源软件提供 ,允许您在商业和开源程序中使用 Lucene
- 100%-pure Java
- 可用的其他编程语言中的实现是索引兼容的
Apache 软件基金会
在 Apache 软件基金会提供的开源软件项目的 Apache 社区的支持。
但是 Lucene 只是一个框架,要充分利用它的功能,需要使用 JAVA,并且在程序中集成 Lucene。需要很多的学习了解,才能明白它是如何运行的,熟练运用 Lucene 确实非常复杂。
Solr
Apache Solr 是一个基于名为 Lucene 的 Java 库构建的开源搜索平台。它以用户友好的方式提供 Apache Lucene 的搜索功能。作为一个行业参与者近十年,它是一个成熟的产品,拥有强大而广泛的用户社区。它提供分布式索引,复制,负载平衡查询以及自动故障转移和恢复。如果它被正确部署然后管理得好,它就能够成为一个高度可靠,可扩展且容错的搜索引擎。很多互联网巨头,如 Netflix,eBay,Instagram 和亚马逊(CloudSearch)都使用 Solr,因为它能够索引和搜索多个站点。
主要功能列表包括:
- 全文搜索
- 突出
- 分面搜索
- 实时索引
- 动态群集
- 数据库集成
- NoSQL 功能和丰富的文档处理(例如 Word 和 PDF 文件)
ElasticSearch
Elasticsearch 是一个开源(Apache 2 许可证),是一个基于 Apache Lucene 库构建的 RESTful 搜索引擎。
Elasticsearch 是在 Solr 之后几年推出的。它提供了一个分布式,多租户能力的全文搜索引擎,具有 HTTP Web 界面(REST)和无架构 JSON 文档。Elasticsearch 的官方客户端库提供 Java,Groovy,PHP,Ruby,Perl,Python,.NET 和 Javascript。
分布式搜索引擎包括可以划分为分片的索引,并且每个分片可以具有多个副本。每个 Elasticsearch 节点都可以有一个或多个分片,其引擎也可以充当协调器,将操作委派给正确的分片。
Elasticsearch 可通过近实时搜索进行扩展。其主要功能之一是多租户。
主要功能列表包括:
- 分布式搜索
- 多租户
- 分析搜索
- 分组和聚合
总结
那么,到底是 Solr 还是 Elasticsearch?
有时很难找到明确的答案。无论您选择 Solr 还是 Elasticsearch,首先需要了解正确的用例和未来需求。总结他们的每个属性。
记住:
-
由于易于使用,Elasticsearch 在新开发者中更受欢迎。但是,如果您已经习惯了与 Solr 合作,请继续使用它,因为迁移到 Elasticsearch 没有特定的优势。
-
如果除了搜索文本之外还需要它来处理分析查询,Elasticsearch 是更好的选择。
-
如果需要分布式索引,则需要选择 Elasticsearch。对于需要良好可伸缩性和性能的云和分布式环境,Elasticsearch 是更好的选择。
-
两者都有良好的商业支持(咨询,生产支持,整合等)
-
两者都有很好的操作工具,尽管 Elasticsearch 因其易于使用的 API 而更多地吸引了 DevOps 人群,因此可以围绕它创建一个更加生动的工具生态系统。
-
Elasticsearch 在开源日志管理用例中占据主导地位,许多组织在 Elasticsearch 中索引它们的日志以使其可搜索。虽然 Solr 现在也可以用于此目的,但它只是错过了这一想法。
-
Solr 仍然更加面向文本搜索。另一方面,Elasticsearch 通常用于过滤和分组 - 分析查询工作负载 - 而不一定是文本搜索。Elasticsearch 开发人员在 Lucene 和 Elasticsearch 级别上投入了大量精力使此类查询更高效 (降低内存占用和 CPU 使用)。因此,对于不仅需要进行文本搜索,而且需要复杂的搜索时间聚合的应用程序,Elasticsearch 是一个更好的选择。
-
Elasticsearch 更容易上手,一个下载和一个命令就可以启动一切。Solr 传统上需要更多的工作和知识,但 Solr 最近在消除这一点上取得了巨大的进步,现在只需努力改变它的声誉。
-
在性能方面,它们大致相同。我说“大致”,因为没有人做过全面和无偏见的基准测试。对于 95%的用例,任何一种选择在性能方面都会很好,剩下的 5%需要用它们的特定数据和特定的访问模式来测试这两种解决方案。
-
从操作上讲,Elasticsearch 使用起来比较简单 - 它只有一个进程。Solr 在其类似 Elasticsearch 的完全分布式部署模式 SolrCloud 中依赖于 Apache ZooKeeper。ZooKeeper 是超级成熟,超级广泛使用等等,但它仍然是另一个活跃的部分。也就是说,如果您使用的是 Hadoop,HBase,Spark,Kafka 或其他一些较新的分布式软件,您可能已经在组织的某个地方运行 ZooKeeper。
-
虽然 Elasticsearch 内置了类似 ZooKeeper 的组件 Xen,但 ZooKeeper 可以更好地防止有时在 Elasticsearch 集群中出现的可怕的裂脑问题。公平地说,Elasticsearch 开发人员已经意识到这个问题,并致力于改进 Elasticsearch 的这个方面。
-
如果您喜欢监控和指标,那么使用 Elasticsearch,您将会进入天堂。这个东西比新年前夜在时代广场可以挤压的人有更多的指标!Solr 暴露了关键指标,但远不及 Elasticsearch 那么多。
总之,两者都是功能丰富的搜索引擎,只要设计和实现得当,它们或多或少都能提供相同的性能。
评论区