C#,全文检索的原理与实现代码,No-Lucene

这篇具有很好参考价值的文章主要介绍了C#,全文检索的原理与实现代码,No-Lucene。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 文档管理系列技术文章

文档管理系统的核心技术与难点https://blog.csdn.net/beijinghorn/article/details/122426112PB级全文检索(分布式)解决方案——HyperSearchhttps://blog.csdn.net/beijinghorn/article/details/122377760

概述

 全文检索是文档管理系统的核心功能。 

实现全文检索的途径其实很多,包括但不限于通过建立“倒排序索引”的全文搜素技术。当然,“倒排序索引”是主流,效益比较高。比如,始于很久以前的、技术落后Lucene及其继承者ES,仍然获得了很好的发展空间。本文用很少的代码实现基于“倒排序索引”技术的全文检索,大家体会一下小玩具。

一、全文检索的基础流程

实现全文检索需要三个核心步骤:

(1)构建:获取数据记录,并建立文本信息的倒排序索引;

(2)使用:对每个搜索词,获取其倒排序索引信息,进行集合的“交”运算;

(3)显示:以最终的索引信息,建立显示结果;

对于初学者,了解全文检索的原理,这就够了。

但对于应用软件而言,还需要更完善的流程。

二、全文检索的高级流程

高级流程分“系统构建期”与“应用期”。

系统构建期:

(1)获取原始数据记录,并建立文本信息的倒排序索引;

(2)将所有索引信息保存至文件,便于应用读取;

系统应用期:

(1)读取索引信息;

(2)增加、删除(修改)数据记录;同步或异步增加、删除(修改)索引信息,并保存至索引文件。为了保证系统效率,一般采用异步形式。大型系统通过应用服务器,实现分布式存储、分布式搜索。

(3)搜索语句的分词与语法处理;

(4)对每个搜索词,获取其倒排序索引信息,进行集合的“交”“并”“差”运算;

(5)以最终的索引信息,建立结果显示;

三、实验性全文检索系统的原理性源代码

先看看效果。

c# 附件全文搜索,C#算法演义 Algorithm Recipes,c#,开发语言,全文检索,算法,链表

再上完整的源代码。

using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;

namespace WindowsFormsApp3
{
    public partial class Form1 : Form
    {
        string sourceFolder = String.Empty;
        Hashtable hashIndex = new Hashtable();
        List<DocumentInfo> documentList = new List<DocumentInfo>();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        private void button1_Click(object sender, EventArgs e)
        {
            sourceFolder = Path.Combine(Application.StartupPath, @"Text");
            DirectoryInfo root = new DirectoryInfo(sourceFolder);
            FileInfo[] xfiles = root.GetFiles();
            hashIndex.Clear();
            documentList.Clear();
            StringBuilder sb = new StringBuilder();
            foreach (FileInfo xfile in xfiles)
            {
                DocumentInfo dx = new DocumentInfo(documentList.Count, xfile.FullName);
                documentList.Add(dx);
                CreateIndex(dx);
                sb.AppendLine(dx.Filename + "<br>");
            }
            button1.Enabled = false;
            button2.Visible = true;
            textBox1.Visible = true;
            sb.AppendLine("索引创建完成!<br>");
            webBrowser1.DocumentText = sb.ToString();
        }
        private void CreateIndex(DocumentInfo docInfo)
        {
            // 创建文本文件索引信息,构建“倒序索引表”
            string buf = File.ReadAllText(docInfo.Filename);
            buf = buf.Replace(" ", " ").ToLower();
            for (int i = 0; i < buf.Length; i++)
            {
                string bs = buf.Substring(i, 1).Trim();
                if (bs.Length == 0) continue;
                if (Char.IsPunctuation(bs[0])) continue;
                if (hashIndex.ContainsKey(bs))
                {
                    List<IndexInfo> index = (List<IndexInfo>)hashIndex[bs];
                    index.Add(new IndexInfo(docInfo.Id, i));
                }
                else
                {
                    List<IndexInfo> index = new List<IndexInfo>();
                    index.Add(new IndexInfo(docInfo.Id, i));
                    hashIndex.Add(bs, index);
                }
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            string queryString = textBox1.Text.Trim().ToLower();
            if (queryString.Length == 0) return;
            List<IndexInfo> result = new List<IndexInfo>();
            for (int i = 0; i < queryString.Length; i++)
            {
                string bs = queryString.Substring(i, 1).Trim();
                if (bs.Length == 0) continue;
                if (!hashIndex.ContainsKey(bs)) { break; }
                List<IndexInfo> rx = (List<IndexInfo>)hashIndex[bs];
                if (result.Count == 0)
                {
                    result.AddRange(rx);
                }
                else
                {
                    // 数据多,会慢。仅为说明原理,用暴力匹配算法!
                    List<IndexInfo> ry = new List<IndexInfo>();
                    for (int j = 0; j < rx.Count; j++)
                    {
                        for (int k = 0; k < result.Count; k++)
                        {
                            if (result[k].Id == rx[j].Id)
                            {
                                if (rx[j].Position == (result[k].Position + 1))
                                {
                                    ry.Add(rx[j]);
                                }
                            }
                        }
                    }
                    result = ry;
                    if (result.Count == 0) { break; }
                }
            }
            if (result.Count == 0) { webBrowser1.DocumentText = "无!"; return; }
            // 按位置倒序
            result.Sort(delegate (IndexInfo a, IndexInfo b) { return Comparer<int>.Default.Compare(a.Position, b.Position); });
            webBrowser1.DocumentText = ResultShow(queryString,result);
        }
        private string ResultShow(string queryString, List<IndexInfo> result)
        {
            int left_span = 16;
            int span_length = 256;
            Hashtable hx = new Hashtable();
            StringBuilder sb = new StringBuilder();
            foreach (IndexInfo record in result)
            {
                if (hx.ContainsKey(record.Id) == false)
                {
                    DocumentInfo dx = documentList.Find(t => t.Id == record.Id);
                    string buf = File.ReadAllText(dx.Filename).Replace(" ", " ");
                    sb.AppendLine("<a href=''><h2>" + dx.Filename.Substring(sourceFolder.Length + 1) + "</h2></a>");
                    int s1 = record.Position < left_span ? 0 : record.Position - left_span;
                    int s2 = ((s1 + span_length) < buf.Length) ? (s1 + span_length) : (s1 + (buf.Length - s1));
                    sb.AppendLine(buf.Substring(s1, s2 - s1) + "<br><br>");
                    hx.Add(record.Id, true);
                }
            }
            return sb.ToString().Replace(queryString, "<font color=red>" + queryString + "</font>");
        }
    }
    public class DocumentInfo
    {
        public int Id { get; set; } = 0;
        public string Filename { get; set; } = String.Empty;
        public DocumentInfo(int id, string filename) { Id = id; Filename = filename; }
    }
    public class IndexInfo
    {
        public int Id { get; set; } = 0;
        public int Position { get; set; } = 0;
        public IndexInfo(int id, int position) { Id = id; Position = position; }
    }
}

支持(单个)汉字、英文单词(部分、不管大小写)的搜索。如果把 ToLower() 去掉,可以支持大小写敏感的搜索。

又及:

看完代码,大家可能会问?全文检索怎么能没有分词?

大叔的理解:在新词日新月异的今天,在信息逐渐碎片化的今天,在内存外存都很便宜的今天,在算力大大富裕的今天,分词是没有任何意义的。尤其,对于Unicode双码(如汉字)的分词研究开发,纯属浪费时间和博取论文量而已。

 ——————————————————————

POWER BY 315SOFT.COM &
TRUFFER.CN文章来源地址https://www.toymoban.com/news/detail-780011.html

到了这里,关于C#,全文检索的原理与实现代码,No-Lucene的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mysql 简单实现全文检索(FULLTEXT)

    版本支持 MySQL 5.6 以前的版本,只有 MyISAM 存储引擎支持全文索引; MySQL 5.6 及以后的版本,MyISAM 和 InnoDB 存储引擎均支持全文索引; 只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引。 按顺序操做: 1.修改数据库配置 etc/my.cnf 文件 [mysqld] 下面加入 ngram_token_s

    2024年02月09日
    浏览(44)
  • MySQL使用全文检索实现模糊搜索

    创建全文检索有两种方式 方式一: 方法二: in boolean mode(布尔模式): 可以为检索的字符串增加操作符,且不会像自然语言一样自动拆词查询并集(除非手动空格隔开) 全文检索模糊查询使用全文索引来提高搜索效率,可以快速查询大数据量中的模糊匹配结果。而LIKE模糊查

    2024年02月15日
    浏览(50)
  • ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo

    需求 做一个类似百度的全文搜索功能 搜素自动补全(suggest) 分词全文搜索 所用的技术如下: ElasticSearch Kibana 管理界面 IK Analysis 分词器 SpringBoot 实现流程 可以通过 Canal 对 MySQL binlog 进行数据同步,或者 flink 或者 SpringBoot 直接往ES里添加数据 当前以 SpringBoot 直接代码同

    2024年02月03日
    浏览(44)
  • Mysql 实现类似于 ElasticSearch 的全文检索功能

    ​ 一、前言 今天一个同事问我,如何使用 Mysql 实现类似于 ElasticSearch 的全文检索功能,并且对检索跑分?我当时脑子里立马产生了疑问?为啥不直接用es呢?简单好用还贼快。但是听他说,数据量不多,客户给的时间非常有限,根本没时间去搭建es,所以还是看一下

    2024年02月03日
    浏览(46)
  • SpringBoot封装Elasticsearch搜索引擎实现全文检索

    注:本文实现了Java对Elasticseach的分页检索/不分页检索的封装 ES就不用过多介绍了,直接上代码: 创建Store类(与ES字段对应,用于接收ES数据) Elasticsearch全文检索接口:不分页检索 Elasticsearch全文检索接口:分页检索 本文实现了Java对Elasticsearch搜索引擎全文检索的封装 传入

    2024年02月04日
    浏览(45)
  • MySQL全文检索临时代替ES实现快速搜索

    引入 在MySQL 5.7.6之前,全文索引只支持英文全文索引,不支持中文全文索引,需要利用分词器把中文段落预处理拆分成单词,然后存入数据库。 从MySQL 5.7.6开始,MySQL内置了ngram全文解析器,用来支持中文、日文、韩文分词。 全文索引只支持InnoDB和MyISAM引擎,支持的类型为C

    2024年02月07日
    浏览(50)
  • 基于Lucene的全文检索系统的实现与应用

    Lucene是一个开源的全文搜索引擎库,用于实现文本索引和搜索功能。它提供了强大的搜索和排序功能,可以用于构建各种类型的搜索应用程序,如网站搜索引擎、文档管理系统等。Lucene支持多种编程语言,并且具有高性能和可扩展性。它是许多其他搜索引擎和文本处理工具的

    2024年02月04日
    浏览(60)
  • 基于Solr的全文检索系统的实现与应用

    Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。 Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr 索引的实现方法很简单,

    2024年02月04日
    浏览(44)
  • 【springboot微服务】Lucence实现Mysql全文检索

    目录 一、前言 1.1 常规调优手段 1.1.1 加索引 1.1.2 代码层优化 1.1.3 减少关联表查询

    2023年04月12日
    浏览(46)
  • SpringBoot整合Lucene实现全文检索【详细步骤】【附源码】

    同样,本文的出现,也是我的个人网站笑小枫搭建的过程中产生的,作为一个技术博客为主的网站,Mysql的搜索已经满足不了我的野心了,于是,我便瞄上了全文检索。最初,是打算直接使用比较熟悉的ES,但是考虑到部署ES额外的服务器资源开销,最后选择了Lucene,搭配IK分

    2024年02月04日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包