全文索引 Lucene.Net
Lucene.net 是什么
主要解决用户输入的搜索关键词不精确的问题;关系型数据库只能=<> like 检索
分词 :把一个搜素的长句子,拆分成各种单词,通过单词去匹配,查询到数据;不在是基于关系型数据库来查询了;而是基于全文索引
Lucene.net 是一个高性能的全能的全文检索的搜索引擎框架库,完全使用c#开发。是一种技术,任何一种需要全文检索的应用 下载链接 :https://lucenenet.apache.org/download/download.html
Lucene.net应用
-
一进一出
-
一进:从关系型数据库中生成Lucene索引(要通过分词存储)
-
一出:查询,通过查询条件,也经过分词——到Luncene索引中匹配的到数据(不在是基于关系型数据库查询了);
-
Lucene.net七大对象介绍
-
Analysis:分词器,负责把字符串拆分成原子,包含了标准分词,直接空格拆分。项目中用的是盘古中文分词,
-
Document:数据结构,定义存储数据的格式
-
Index:索引的读(IndexWriter)写(IndexReader)类
-
QueryParser:查询解析器,负责解析查询语句,查询的时候,需要组件的各种查询条件
-
Search:负责各种查询类,命令解析后得到就是查询类,从索引中,提取数据
-
Store:索引存储类,负责文件夹等等
-
Util:常见工具类库
Lucene.net query方式
-
Search
-
TermQuery:单元查询
-
new Term("titile","张三");=》title:张三
-
-
BoolenQuery:多条件查询
-
new Term("title",“张三") and new Term("title","李四") ; =》 titile :张三 + title :李四
-
new Term("title","张三") or new Term("title","李四"):=》 titile :张三 title :李四
-
-
WildcardQuery:通配符查询:
-
new Term("title","张?")=》 title:张?
-
new Term("title","张")=》 title:张
-
-
PrefixQuery:前缀查询; 以XX开头。
-
PhraseQuery: 间隔查询 ;
-
包含A和F , 但是 A和F之前的间隔不超过5个字符
-
-
FuzzQuery: 近似查询,
-
NumberIcRangeQuery: 范围查询;[1,100]
-
lucene.net索引建立和查询
Nuget 安装
-
Lucene.Net
-
Lucene.Net.Analysis.PanGu (盘古分词,第三方分词器)
-
词典可以手动去维护
1 public class student{ 2 public int id {get;set;} 3 public string name {get;set;} 4 public double achievement {get;set;} 5 } 6 //初始化索引 7 public class luceneTest{ 8 public static void initIndex(){ 9 List<student> list =new List<student>();//这个应该是一个有数据的list 10 FSDirectory directory =FSDirectory.Open("" );//文件夹 11 using(IndexWriter writer =new IndexWriter(directory,new PanGuAnalyzer(),true,IndexWrite.MaxFlieIdLength。LIMITED))//索引写入器 12 { 13 foreach(student s in list ){ 14 Document doc =new Document();//一条数据 15 doc.Add(new FileId("id",s.id.ToString().FileId.Store.NO,FileId.Index.NOT_ANALYZED));//一个字段 列名 值 是否保存值 是否分词 16 doc.Add(new FileId(“name”,s.name,FileId.Store.YES,FileId.Index.AYYLZED)); 17 doc.Add(new NumericFileId("achievement",File.Store.YES,true)).SetDoubleValue(s.achievement); 18 doc.Add(new NumericField("time", Field.Store.YES, true).SetIntValue(int.Parse(DateTime.Now.ToString("yyyyMMdd")) )); 19 writer.AddDocument(doc);//写入到缓冲区 20 } 21 writer.Optimize();//优化,就是合并 22 } 23 } 24 public static void show(){ 25 FSDirectory dir = FSDirectory.Open(""); 26 IndexSearcher searcher = new IndexSearcher(dir);//查找器 27 //1、直接根据关键字查找 28 { 29 TermQuery query = new TermQuery(new Term("name", "霍某"));//包含 30 TopDocs docs = searcher.Search(query, null, 10000);//找到的数据 31 foreach (ScoreDoc sd in docs.ScoreDocs) 32 { 33 Document doc = searcher.Doc(sd.Doc); 34 Console.WriteLine(string.Format("id={0}", doc.Get("id"))); 35 Console.WriteLine(string.Format("name={0}", doc.Get("name"))); 36 } 37 } 38 //2、将关键字解析成查找器 39 QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "name", new PanGuAnalyzer());//解析器,用于解析关键字 40 { 41 string keyword = "霍某有两只猫"; 42 { 43 Query query = parser.Parse(keyword); 44 TopDocs docs = searcher.Search(query, null, 10000);//找到的数据 45 foreach (ScoreDoc sd in docs.ScoreDocs) 46 { 47 Document doc = searcher.Doc(sd.Doc); 48 Console.WriteLine(string.Format("id={0}", doc.Get("id"))); 49 Console.WriteLine(string.Format("name={0}", doc.Get("name"))); 50 } 51 } 52 //3、根据price字段过滤,查询价格在300-1200之间的数据,并按照price和time字段排序 53 { 54 Query query = parser.Parse(keyword); 55 NumericRangeFilter<int> timeFilter = NumericRangeFilter.NewIntRange("achievement", 300, 1200, true, true);//过滤 56 SortField sortPrice = new SortField("achievement", SortField.DOUBLE, false);//降序 57 SortField sortTime = new SortField("time", SortField.INT, true);//升序 58 Sort sort = new Sort(sortTime, sortPrice);//排序 哪个前哪个后 59 60 TopDocs docs = searcher.Search(query, timeFilter, 10000, sort);//找到的数据 61 int i = -1; 62 foreach (ScoreDoc sd in docs.ScoreDocs) 63 { 64 i++; 65 if (i>=0 && i < 20) //可以在这里写分页, 66 { 67 Document doc = searcher.Doc(sd.Doc); 68 Console.WriteLine(string.Format("id={0}", doc.Get("id"))); 69 Console.WriteLine(string.Format("name={0}", doc.Get("name"))); 70 } 71 } 72 } 73 } 74 75 76 } 77 78 }
浙公网安备 33010602011771号