全局搜索——Lucene.Net与盘古分词的实现思路
一、Lucene.Net
1、Lucene.Net介绍:
Lucene.Net是一个C#开发的开源全文索引库(自带的有索引管理、分词、查询)
- Lucene.Net.Index 提供索引管理,词组排序。
- Lucene.Net.Search 提供查询相关功能。
- Lucene.Net.Store 支持数据存储管理,主要包括I/O操作。
- Lucene.Net.Util 公共类。
- Lucene.Net.Documents 负责描述索引存储时的文件结构管理。
- Lucene.Net.QueryParsers 提供查询语法。
- Lucene.Net.Analysis 负责分析文本。
由于Lucene.Net自带的分词算法对于中文的分词不是很强大,所以我们在分词这块采用盘古分词
2、Lucene的索引的数据结构
索引底层也是采用类似二叉树的表的结构
在lucene中最基本的概念是索引(index),文档(document),域(field)和项(term),他们之间的基本关系是这样的:
一个索引包含一系列的文档;
一个文档是一系列域的集合
一个域是一系列命了名称的项的集合
一个项是一个字符串
或者这样理解,如果把整个看作是
索引——一个数据表,
域——这个数据表中的某一列
项——对应某一列中的字符串关键字。也就是我们通常意义上的字符串分词以后的关键字
文档——可以看成是一次插入到数据库中的所有数据的集合。
所以说,如果相同的字符串在不同的域中肯定是作为不同的项来对待的,项(terms)被标成成为字符串对的形式:第一个字符串用来命名域(field),第二个用来表示该域下文本的值
倒排索引:索引文件为了使得以项(term)为基础的搜索更加有效而储存有所有项(term)的统计数字。Lucene的索引使用的是一种叫做倒排索引(inverted index)的索引方式,这是因为,这种索引方式是从特定的关键字可以列出所有包含它的文档,与通常方式的由文档列出所有关键字正好是反过来的,类似Mysql的索引(B+树的结构)
域的类型:在lucene中,域可能被储存,在这种情况下这些域下的文本被按照字面意义的按照通常方式存储下来,被倒排的域称为索引了的域。一个域可能既被存储又被索引
域中的内容可能被分词成为一个个的项来进行索引,也有可能整个域下的内容就作为一个项来进行索引。类比到SQL server中的情形:我们说的前一种情况可以类比到那种某一列由大段文本组成,然后我们对这一列进行全文索引,然后文本会被分词程序分成一个个的关键词。然后索引。后一种情况类比到某一列的数据类型为datetime或者干脆为int类型,有时候我们需要为这样的列进行索引比如说取出某时间点之前存入的所有数据等等。这个时候我们没有必要也不会去对这样的类型分词以后索引,而是对整个域中的内容索引。还有一种情况就是,域中的内容只分词以后进行索引,但是不进行储存。这样的情况可以对应到进行web搜索时的头部meta信息。对于这样的信息我们只需要索引,不需要进行储存
段:段这个概念不好理解,官方的解释是这样的:lucene的索引可能由若干子索引(sub-index)或者段(segment)组成。每一个段都是一个相对独立的可以单独进行搜索的索引。lucene的索引是这样产生的:
1、为新加入到全文索引中的文档创建单独的段结构
2、合并已经存在的段
Lucene索引实现
Lucene的索引不是B+Tree组织的,而是倒排索引,Lucene的倒排索引由Term index,Team Dictionary和Posting List组成。

有倒排索引(invertedindex)就有正排索引(forwardindex),正排索引就是文档(Document)和它的字段Fields正向对应的关系:
|
DocID |
name |
sex |
age |
|
1 |
jack |
男 |
18 |
|
2 |
lucy |
女 |
17 |
|
3 |
peter |
男 |
17 |
倒排索引是字段Field和拥有这个Field的文档对应的关系:
Sex字段:
|
男 |
[1,3] |
|
女 |
[2] |
Age字段:
|
18 |
[1] |
|
17 |
[2,3] |
如果我们查的是男,我们很容易把含有男的1和3条数据找出来
Jack,lucy或者17,18这些叫做term,而[1,3]就是posting list。Posting list就是一个int型的数组,存储了所有符合某个term的文档id。那么什么是Term index和Term dictionary?
如上,假设name字段有很多个term,比如:Carla,Sara,Elin,Ada,Patty,Kate,Selena
如果按照这样的顺序排列,找出某个特定的term一定很慢,因为term没有排序,需要全部过滤一遍才能找出特定的term。排序之后就变成了:Ada,Carla,Elin,Kate,Patty,Sara,Selena
这样就可以用二分查找的方式,比全遍历更快地找出目标的term。如何组织这些term的方式就是 Term dictionary,意思就是term的字典。有了Term dictionary之后,就可以用比较少的比较次数和磁盘读次数查找目标。但是磁盘的随机读操作仍然是非常昂贵的,所以尽量少的读磁盘,有必要把一些数据缓存到内存里。但是整个Term dictionary本身又太大了,无法完整地放到内存里。于是就有了Term index。Term index有点像一本字典的大的章节表。比如:
A开头的term ……………. Xxx页
C开头的term ……………. Xxx页
E开头的term ……………. Xxx页
如果所有的term都是英文字符的话,可能这个term index就真的是26个英文字符表构成的了。但是实际的情况是,term未必都是英文字符,term可以是任意的byte数组。而且26个英文字符也未必是每一个字符都有均等的term,比如x字符开头的term可能一个都没有,而s开头的term又特别多。实际的term index是一棵trie 树:

上图例子是一个包含 "A", "to", "tea", "ted", "ten", "i", "in", 和 "inn" 的trie树。这棵树不会包含所有的term,它包含的是term的一些前缀。通过term index可以快速地定位到term dictionary的某个offset,然后从这个位置再往后顺序查找。再加上一些压缩技术(想了解更多,搜索 Lucene Finite State Transducers),Term index的尺寸可以只有所有term的尺寸的几十分之一,使得用内存缓存整个term index变成可能。整体上来说就是这样的效果:

3、检索的过程

全局搜索——Lucene.Net与盘古分词的实现思路的更多相关文章
- Lucene.net 全文检索 盘古分词
lucene.net + 盘古分词 引用: 1.Lucene.Net.dll 2.PanGu.Lucene.Analyzer.dll 3.PanGu.HighLight.dll 4.PanGu.dll ...
- Lucene.Net和盘古分词应用
Lucene.Net.dll:用做全文索引 PanGu.dll(盘古分词):作为中文分词的条件 大致原理: 1.Lucene先根据PanGu将需要搜索的内容分隔.分词,然后根据分词的结果,做一个索引页 ...
- Lucene.Net 与 盘古分词
1.关键的一点,Lucene.Net要使用3.0下面的版本号,否则与盘古分词接口不一致. 关键代码例如以下 using System; using System.IO; using System.Co ...
- Net Core使用Lucene.Net和盘古分词器 实现全文检索
Lucene.net Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎, ...
- Lucene.net入门学习(结合盘古分词)
Lucene简介 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整 ...
- Lucene.net入门学习(结合盘古分词)(转载)
作者:释迦苦僧 出处:http://www.cnblogs.com/woxpp/p/3972233.html 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显 ...
- 【原创】Lucene.Net+盘古分词器(详细介绍)
本章阅读概要 1.Lucenne.Net简介 2.介绍盘古分词器 3.Lucene.Net实例分析 4.结束语(Demo下载) Lucene.Net简介 Lucene.net是Lucene的.net移 ...
- 站内搜索——Lucene +盘古分词
为了方便的学习站内搜索,下面我来演示一个MVC项目. 1.首先在项目中[添加引入]三个程序集和[Dict]文件夹,并新建一个[分词内容存放目录] Lucene.Net.dll.PanGu.dll.Pa ...
- Lucene.Net+盘古分词->开发自己的搜索引擎
//封装类 using System;using System.Collections.Generic;using System.Linq;using System.Web;using Lucene. ...
- Lucene.Net+盘古分词器(详细介绍)(转)
出处:http://www.cnblogs.com/magicchaiy/archive/2013/06/07/LuceneNet%E7%9B%98%E5%8F%A4%E5%88%86%E8%AF%8 ...
随机推荐
- 首个“全4K”运动会,上云!
采用"全4K"超高清制作标准的世-界级赛事--成都世界大学生运动会,可以用手机看.用电视看,甚至用VR沉浸式观看,并且既高清又流畅--在"2023数字科技生态大会&quo ...
- redis 过期监听配置
package org.jeecg.config; import java.lang.reflect.Method; import java.time.Duration; import java.ut ...
- RocketMQ实战—7.生产集群部署和生产参数
大纲 1.RocketMQ生产集群部署和生产参数分析 2.RocketMQ生产集群10wTPS压测 3.RocketMQ生产级故障案例 1.RocketMQ生产集群部署和生产参数分析 (1)服务器数量 ...
- [记录点滴] luaxml编译过程
[记录点滴] luaxml编译 记录一次luaxml编译的解决过程 参考 http://blog.csdn.net/dc_show/article/details/38957991 0x01 编译错误 ...
- Q: 如何实现右键选择打开文件的应用程序
1.win+R打开cmd窗口,输入regedit,打开注册表 2.依次找到HKEY_CLASSESS_ROOT->*->Shell,下面新建项 "用notepad打开" ...
- 旅行商问题(TSP)概述
旅行商问题(TSP)概述 1. TSP问题的复杂性 定义:旅行商问题(Traveling Salesman Problem, TSP)是给定一系列城市及其之间的距离,要求找到一条最短路径,使得旅行商从 ...
- 让 LLM 来评判 | 评估你的评估结果
评估你的评估结果 这是 让 LLM 来评判 系列文章的第三篇,敬请关注系列文章: 基础概念 选择 LLM 评估模型 设计你自己的评估 prompt 评估你的评估结果 奖励模型相关内容 技巧与提示 在生 ...
- MAC消息认证码介绍
此MAC是密码学概念,与计算机网络不同 为什么有了摘要算法还要有MAC 摘要算法保障的是消息的完整性 归根到底就是由H(x)来保证x的完整 那么问题来了,如果我知道你所使用的摘要算法(例如中间人攻击) ...
- MyBatis mapper.xml中SQL处理小于号与大于号 和小于等于号
这种问题在xml处理sql的程序中经常需要我们来进行特殊处理. 其实很简单,我们只需作如下替换即可避免上述的错误: < <= > >= & ' " < ...
- Deepseek学习随笔(3)--- 高效提问技巧
明确需求 在与 DeepSeek 互动时,明确需求是获取高质量回复的关键.以下是一些示例: 错误示例:帮我写点东西 这样模糊的指令无法让 DeepSeek 理解你的具体需求,生成的回复可能无法满足你的 ...