全文索引 Lucene.Net

Lucene.net 是什么

主要解决用户输入的搜索关键词不精确的问题;关系型数据库只能=<> like 检索

分词 :把一个搜素的长句子,拆分成各种单词,通过单词去匹配,查询到数据;不在是基于关系型数据库来查询了;而是基于全文索引

Lucene.net 是一个高性能的全能的全文检索的搜索引擎框架库,完全使用c#开发。是一种技术,任何一种需要全文检索的应用 下载链接 :https://lucenenet.apache.org/download/download.html

Lucene.net应用

  • 一进一出

    • 一进:从关系型数据库中生成Lucene索引(要通过分词存储)

    • 一出:查询,通过查询条件,也经过分词——到Luncene索引中匹配的到数据(不在是基于关系型数据库查询了);

Lucene.net七大对象介绍

  1. Analysis:分词器,负责把字符串拆分成原子,包含了标准分词,直接空格拆分。项目中用的是盘古中文分词,

  2. Document:数据结构,定义存储数据的格式

  3. Index:索引的读(IndexWriter)写(IndexReader)类

  4. QueryParser:查询解析器,负责解析查询语句,查询的时候,需要组件的各种查询条件

  5. Search:负责各种查询类,命令解析后得到就是查询类,从索引中,提取数据

  6. Store:索引存储类,负责文件夹等等

  7. 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 安装

  1. Lucene.Net

  2. 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 }

 

 

posted @ 2022-04-02 14:18  .NetCat  阅读(103)  评论(0)    收藏  举报