欢迎访问shiker.tech

请允许在我们的网站上展示广告

您似乎使用了广告拦截器,请关闭广告拦截器。我们的网站依靠广告获取资金。

全文检索初探
(last modified Apr 20, 2024, 10:48 PM )
by
侧边栏壁纸
  • 累计撰写 174 篇文章
  • 累计创建 60 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

全文检索初探

橙序员
2024-04-20 / 0 评论 / 0 点赞 / 87 阅读 / 2,441 字
文章摘要(AI生成)

全文检索是一种在文本文档或记录集合中快速搜索的技术,其主要包括建立索引、搜索查询、评分和语言处理。建立索引是将文本数据建立索引以便快速检索,搜索查询允许用户按关键字或查询搜索文本数据,评分可根据匹配程度对结果进行排序,而语言处理则提高了检索的准确性和覆盖范围。与全文检索不同,全文查找更简单直接,可能不包括复杂的索引、评分或语言处理技术。在使用MySQL进行文本搜索时,是通过顺序查找实现的,而在使用Elasticsearch或Solr等工具时,则通过分词和关键词匹配来提高搜索效率。因此,全文检索的实现方式包括MySQL全文索引、MongoDB全文索引和Elastic全文检索等。


全文检索是一种用于在文本文档或记录集合中进行快速搜索的技术。它旨在让用户能够按照其关键字或查询来查找文档、文章、记录或其他文本数据。

全文检索通常涉及以下几个方面:

  1. 建立索引:全文检索引擎会对文本数据建立索引,以便能够快速地检索文档。这些索引可以包括单词、短语或其他文本单位的位置和频率信息。
  2. 搜索查询:用户可以使用关键字、短语或其他查询条件来搜索文本数据。搜索引擎会根据查询条件查找匹配的文档,并返回结果。
  3. 评分:在某些全文检索系统中,检索结果可能会根据文档与查询之间的匹配程度进行评分,以便将最相关的文档排在前面。
  4. 语言处理:全文检索系统可能会应用语言处理技术,如词干提取、同义词扩展等,以提高检索的准确性和覆盖范围。

全文查找和检索的差异

一些同学可能会认为mysql也能实现全文检索,这种说法便是混淆了全文检索与全文查找的定义:

  1. 全文检索:通常用于描述一种更广泛的技术和系统,包括建立索引、执行查询、评分等功能。全文检索可能涉及到对文本数据进行索引、语言处理和相关性评分等步骤,以提供更丰富和更复杂的搜索功能。
  2. 全文查找:有时可能用于描述更简单、直接的文本搜索操作,可能不涉及到复杂的索引、评分或语言处理技术。全文查找可能更侧重于基本的搜索功能,例如简单地查找文档中是否包含特定的关键字或短语。

我们通过下面一个用例便能知道两者区别:

我们假设有一段文本:

Spring 灵活的库受到全世界开发人员的信赖。 Spring 每天为数百万最终用户提供令人愉悦的体验 - 无论是流媒体电视,网上购物,或无数其他创新解决方案。 Spring 还得到了所有科技巨头的贡献,包括阿里巴巴、亚马逊、谷歌、微软等。

我们想要查找“科技巨头”时,使用mysql语句:

select * from table where text like "%科技巨头%"

这就会通过遍历进行顺序查找:

image-1713623612910

但是,假如我们使用es、solr这种检索时,其会通过分词将我们的查找方式变为:

image-1713623631724

这两种查找思想,一种是通过关键词在原文中一行一行比较,一种是提取原文关键词,通过关键词匹配确定是否能够命中文档。

全文检索的几种实现方式

MySql全文索引

  1. 创建全文索引:首先,需要在需要进行文本搜索的表的一个或多个文本列上创建全文索引。只有具有全文索引的列才能进行全文搜索。例如,如果要在 content 列上进行全文搜索,可以使用以下命令创建全文索引:

    ALTER TABLE your_table_name ADD FULLTEXT INDEX idx_content (content);
    
  2. 执行全文搜索:一旦创建了全文索引,就可以使用 MATCH ... AGAINST 来执行全文搜索。这个语法允许您指定要搜索的列、搜索的关键字或短语以及其他选项。

    SELECT * FROM your_table_name WHERE MATCH(content) AGAINST('your_search_keyword');
    

    在这个查询中,content 是您想要搜索的列,'your_search_keyword' 是您要搜索的关键字或短语。

  3. 添加条件:您可以通过在 WHERE 子句中添加其他条件来进一步筛选搜索结果。例如,假设有一个名为 articles 的表,其中包含 titlebody 列,可以按照以下方式进行全文搜索:

    SELECT * FROM articles WHERE MATCH(title, body) AGAINST('your_search_keyword');
    

    这将返回包含搜索关键字的标题或正文的所有文章。请注意,全文搜索不区分大小写,并且默认情况下会忽略常见的停用词(如“a”,“and”,“the”等)。

虽然MySQL数据库也支持倒排索引,但目前较少人使用,主要是因为该技术有一些局限性和缺陷。

首先,MySQL的倒排索引只支持单表和简单查询场景。如果涉及到多表关联查询,或者复杂的搜索逻辑,就无法使用倒排索引。此时,需要通过联合查询、文本搜索引擎等其它技术来完成。因此,对于复杂场景,MySQL的倒排索引并不能很好地解决问题。

其次,MySQL的倒排索引性能有一定限制。在数据量较大、写操作较频繁、并发性要求较高的情况下,倒排索引可能会影响整个数据库的性能。这主要是因为倒排索引需要额外的存储空间和计算资源来维护,会占用大量的系统资源。因此,需要根据具体的场景来进行评估和选择,避免在性能上出现瓶颈。

综上所述,MySQL的倒排索引技术并非完全无用,但需要根据具体的场景来进行使用和优化,以充分发挥其优势。在特定的场景下,结合MySQL的倒排索引,可以有效地提高搜索效率,提升用户体验。

MongoDb全文索引

  1. 创建文本索引:首先,在需要进行全文检索的集合上创建一个文本索引。文本索引可以针对一个或多个文档字段创建。例如,如果要在 content 字段上进行全文检索,可以执行以下命令创建文本索引:

    db.collection.createIndex({ content: "text" })
    
  2. 执行文本搜索:一旦创建了文本索引,就可以使用 $text 操作符执行全文检索。可以将 $text 操作符与 $search 操作符一起使用,以指定要搜索的关键字或短语。例如:

    db.collection.find({ $text: { $search: "your_search_keyword" } })
    

    在这个查询中,your_search_keyword 是您要搜索的关键字或短语。

  3. 获取匹配结果:执行文本搜索后,MongoDB 将返回匹配的文档,这些文档根据其与搜索查询的匹配程度进行排序。

mongodb是不支持中文全文检索的(文本搜索语言),因此我们可以通过mongo+中文分词器实现全文检索,即在创建创建文档时对所需文本字段进行分词(以Ansj分词器为例):

    private List<String> getKeyWordsByContent(String content) {
        StopRecognition filter = new StopRecognition();
        //停用词配置
        filter.insertStopNatures("w");
        filter.insertStopNatures("x");
        filter.insertStopNatures("x");
        filter.insertStopNatures("null");
        filter.insertStopRegexes("[\\p{P}\\p{N}\\p{L}]");
        filter.insertStopRegexes("[-]+");
        List<String> keywords =
                IndexAnalysis.parse(content).recognition(filter).getTerms().stream().map(Term::getName).distinct()
                        .collect(Collectors.toList());
        return keywords;
    }

然后对分词后的keywords添加全文索引即可。

Elastic全文检索

  1. 准备数据

    首先,您需要准备要搜索的文档数据,并将其存储在 Elasticsearch 中。文档可以是 JSON 格式的结构化数据,可以包含任意数量的字段和文本内容。

  2. 创建索引

    在将数据存储在 Elasticsearch 中之前,您需要定义一个索引。索引是文档的逻辑容器,它允许您对文档进行分组并定义一组搜索和分析的设置。您可以使用 Elasticsearch 的索引 API 来创建索引,创建完成后连接es。

    RestHighLevelClient client = new RestHighLevelClient(
                    RestClient.builder(new HttpHost("localhost", 9200, "http")));
    
  3. 插入文档

    一旦索引创建好了,您就可以将文档插入到 Elasticsearch 中。您可以使用 Elasticsearch 的文档 API 将文档插入到指定的索引中。

    IndexRequest request = new IndexRequest(indexName)
                        .id("1")
                        .source(Map.of(
                                "title", "Elasticsearch 入门指南",
                                "content", "Elasticsearch 是一个基于 Lucene 的开源搜索引擎",
                                "author", "John Doe"
                        ));
    client.index(request);
    
  4. 执行全文搜索

    当数据插入到 Elasticsearch 中后,您可以使用 Elasticsearch 的查询 API 来执行全文搜索。Elasticsearch 提供了丰富的查询 DSL(Domain Specific Language),您可以使用各种查询来搜索文档。

    // 执行全文搜索
    SearchRequest searchRequest = new SearchRequest(indexName);
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.matchQuery("content", "搜索引擎"));
    searchRequest.source(searchSourceBuilder);
    
    SearchResponse searchResponse = client.search(searchRequest);
    
  5. 处理搜索结果

    执行搜索后,Elasticsearch 将返回与搜索条件匹配的文档。您可以根据需要对搜索结果进行排序、过滤、聚合等操作,以满足具体的业务需求。

    //处理搜索结果
    for (SearchHit hit : searchResponse.getHits().getHits()) {
        System.out.println(hit.getSourceAsString());
    }
    
0

评论区