1:Lucene

Lucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。

2:Pangu分词

盘古分词是一个中英文分词组件。

借用以上两个组件可以对中文分词实现全文搜索。

先说下大概概念

//一、Document//Document:文档对象,是一条原始的数据//二、Field//如果一个字段要显示到最终的结果中,那么一定要存储,否则就不存储//如果要根据这个字段进行搜索,那么这个字段就必须创建索引。//如何确定一个字段是否需要分词?//前提是这个字段首先要创建索引。然后如果这个字段的值是不可分割的,那么就不需要分词。例如:ID//DoubleField、FloatField、IntField、LongField、StringField、TextField这些子类一定会被创建索引,但是不会被分词,而且不一定会被存储到文档列表。要通过构造函数中的参数Store来指定:如果Store.YES代表存储,Store.NO代表不存储//TextField即创建索引,又会被分词。StringField会创建索引,但是不会被分词。//StoreField一定会被存储,但是一定不创建索引//三、Directory//FSDirectory:文件系统目录,会把索引库指向本地磁盘。//特点:速度略慢,但是比较安全//RAMDirectory:内存目录,会把索引库保存在内存。//特点:速度快,但是不安全//四、Analyzer(分词器类) 若有中文 需要第三方类库对中文进行分词 如pangu分词//提供分词算法,可以把文档中的数据按照算法分词//五、IndexWriterConfig(索引写出器配置类)//1) 设置配置信息:Lucene的版本和分词器类型//2)设置是否清空索引库中的数据//六、IndexWriter(索引写出器类)//索引写出工具,作用就是 实现对索引的增(创建索引)、删(删除索引)、改(修改索引)//可以一次创建一个,也可以批量创建索引//核心API//5.2.2.1 QueryParser(查询解析器)//1)QueryParser(单一字段的查询解析器)//2)MultiFieldQueryParser(多字段的查询解析器)//5.2.2.2 Query(查询对象,包含要查询的关键词信息)//1)通过QueryParser解析关键字,得到查询对象//2)自定义查询对象(高级查询)//我们可以通过Query的子类,直接创建查询对象,实现高级查询(后面详细讲)//5.2.2.3 IndexSearch(索引搜索对象,执行搜索功能)//IndexSearch可以帮助我们实现:快速搜索、排序、打分等功能。//IndexSearch需要依赖IndexReader类//查询后得到的结果,就是打分排序后的前N名结果。N可以通过第2个参数来指定://5.2.2.4 TopDocs(查询结果对象)//通过IndexSearcher对象,我们可以搜索,获取结果:TopDocs对象//在TopDocs中,包含两部分信息://int totalHits :查询到的总条数//ScoreDoc[] scoreDocs    : 得分文档对象的数组//5.2.2.5 ScoreDoc(得分文档对象)//ScoreDoc是得分文档对象,包含两部分数据://int doc    :文档的编号----lucene给文档的一个唯一编号//float score    :文档的得分信息//拿到编号后,我们还需要根据编号来获取真正的文档信息

上代码:

1:接口:

public interface IDBService<TContext> where TContext : Microsoft.EntityFrameworkCore.DbContext{TContext Context { get; }}
//为泛型方法封装的。泛型方法里面实现的和搜索类实现的一样。
public interface IService<T>{List<T> QueryToList(int limit);List<T> QueryToList(int start, int end);List<T> QueryToList(string txt);List<T> QueryAll();T QuerySignle(string guid);T QuerySignle(int pk_id);}

2:搜索类:

using System;
using System.Collections.Generic;
using System.Text;
using LuceneCore.Respority;
using LuceneCore.DB;
using Lucene.Net.Store;
using LuceneCore.Util;
using System.Linq;namespace LuceneCore.Respority
{class DbContextService<TDbContext> : IDBService<TDbContext> where TDbContext : Microsoft.EntityFrameworkCore.DbContext{public TDbContext Context { get; }private List<Type> listType = new List<Type>();//private static FSDirectory dir = FSDirectory.Open("");private Lucene.Net.Index.IndexWriter writer = null;// new Lucene.Net.Index.IndexWriter(dir, new Lucene.Net.Analysis.PanGu.PanGuAnalyzer(), Lucene.Net.Index.IndexWriter.MaxFieldLength.LIMITED);private Lucene.Net.Index.IndexReader reader = null;public DbContextService(TDbContext _Context){Context = _Context;foreach (System.Reflection.PropertyInfo pro in Context.GetType().GetProperties()){if (pro.PropertyType.GenericTypeArguments != null && pro.PropertyType.GenericTypeArguments.Length > 0){listType.Add(pro.PropertyType.GenericTypeArguments[0]);}}}public void Test<T>(T t){CreateIndexWriter(@"C:\Users\FanLin\Desktop\index");var list = new List<T>();list.Add(t);CreateIndex(list);QueryByKeyWord<T>("搜索", false, null, 100, null, "NAME");var query1 = CreateQuery<T,Lucene.Net.Search.TermQuery, Util.Attributes.TermQueryAttribute>("搜索");var query = CreateBooleanQuery((query1, Lucene.Net.Search.Occur.SHOULD));QueryBySpecidQuery(query);}/// <summary>/// 创建IndexWriter和IndexReader对象/// </summary>/// <param name="filePath"></param>/// <returns></returns>public (Lucene.Net.Index.IndexWriter, Lucene.Net.Index.IndexReader) CreateIndexWriter(string filePath){FSDirectory dir = FSDirectory.Open(filePath);if (writer == null){writer = new Lucene.Net.Index.IndexWriter(dir, new Lucene.Net.Analysis.PanGu.PanGuAnalyzer(), Lucene.Net.Index.IndexWriter.MaxFieldLength.LIMITED);writer.MergeFactor = 100;//控制多个segment合并的频率,默认10writer.UseCompoundFile = true;//创建符合文件 减少索引文件数量}//var directory = System.IO.Directory.CreateDirectory(filePath);if (reader == null){reader = Lucene.Net.Index.IndexReader.Open(dir, false);}return (writer, reader);}/// <summary>/// 提交/// </summary>private void CommitIndexWriter(){if (writer == null)return;writer.Commit();}//清除private void FlushIndexWriter(){if (writer == null)return;writer.Flush(true, true, true);}/// <summary>/// 关闭/// </summary>private void CloseIndexWriter(){if (writer == null)return;writer.Flush(true, true, true);}/// <summary>/// 创建索引/// </summary>public void CreateIndex<T>(IEnumerable<T> tList){// var config = new IndexWriterConfig(Lucene.Net.Util.LuceneVersion.LUCENE_48, _analyzer);if (writer == null) return;// 遍历实体集,添加到索引库foreach (var entity in tList){this.CreateIndex(entity);}this.CommitIndexWriter();this.CloseIndexWriter();}/// <summary>/// 创建索引/// </summary>private void CreateIndex<T>(T tSignal){if (writer == null) return;if (writer.NumDocs() <= 0){writer.AddDocument(tSignal.ToDocument());}else{this.UpdateIndex(tSignal);}//if (cmit) this.CommitIndexWriter(true);}/// <summary>/// 增加索引/// </summary>private void UpdateIndex<T>(T t){if (writer == null) return;if (reader == null) return;//如果 有先删除writer.UpdateDocument(new Lucene.Net.Index.Term(t.GetCustomAttributeColumn_KeyAndValue<T, System.ComponentModel.DataAnnotations.KeyAttribute>().field, t.GetCustomAttributeColumn_KeyAndValue<T, System.ComponentModel.DataAnnotations.KeyAttribute>().txt), t.ToDocument());}/// <summary>/// 批量修改索引/// </summary>/// <param name="ts"></param>public void UpdateIndexEnumerable<T>(IEnumerable<T> ts){//如果 有先删除foreach (var t in ts){UpdateIndex(t);}this.CommitIndexWriter();this.CloseIndexWriter();}/// <summary>/// 删除索引/// </summary>private void DeleteIndex<T>(T t){if (reader == null) return;reader.DeleteDocuments(new Lucene.Net.Index.Term(t.GetCustomAttributeColumn_KeyAndValue<T, System.ComponentModel.DataAnnotations.KeyAttribute>().field, t.GetCustomAttributeColumn_KeyAndValue<T, System.ComponentModel.DataAnnotations.KeyAttribute>().txt));}/// <summary>/// 批量删除索引/// </summary>public void DeleteIndex<T>(IEnumerable<T> tEnum){if (reader == null) return;foreach (var t in tEnum){DeleteIndex(t);}this.CommitIndexWriter();this.CloseIndexWriter();}/// <summary>/// 删除所有索引/// </summary>public void DeleteAllIndex(){if (writer == null) return;writer.DeleteAll();}/// <summary>///  根据关键字来查询/// </summary>/// <param name="keyWord">查询关键字</param>/// <param name="isMulti">是否对多字段查询</param>/// <param name="filter">过滤条件</param>/// <param name="n">需要查出多少条</param>/// <param name="sort">排序规则</param>/// <param name="filterColumn">对哪些字段做查询</param>/// <returns></returns>public IEnumerable<T> QueryByKeyWord<T>(string keyWord, bool isMulti, Lucene.Net.Search.Filter filter, int n, Lucene.Net.Search.Sort sort, params string[] filterColumn){// 索引搜索工具//IndexSearch可以帮助我们实现:快速搜索、排序、打分等功能。//IndexSearch需要依赖IndexReader类Lucene.Net.Search.IndexSearcher searcher = new Lucene.Net.Search.IndexSearcher(reader);//关键字//string kwyWord = "";Lucene.Net.Search.Query query = null;//参数分别表示:版本号 对哪个字段分词查询 分词器//这是对单一字段做分词查询//单一字段查询 或者多个字段查询if (isMulti && filterColumn.Length <= 1){throw new ArgumentNullException(filter + "为null,请传入需要查询的字段");}if (!isMulti && filterColumn.Length > 1){throw new ArgumentNullException(filter + "当前不是多字段查询,只允许传入一个字段名称!");}Lucene.Net.QueryParsers.QueryParser queryParser = null;if (!isMulti){//对单字段做查询queryParser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_30, filterColumn[0], new Lucene.Net.Analysis.PanGu.PanGuAnalyzer());//解析关键字// query = queryParser.Parse(keyWord);}else{queryParser = new Lucene.Net.QueryParsers.MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, filterColumn, new Lucene.Net.Analysis.PanGu.PanGuAnalyzer());}//解析关键字query = queryParser.Parse(keyWord);//query的分类//返回100条数据// TopDocs(查询结果对象)//通过IndexSearcher对象,我们可以搜索,获取结果:TopDocs对象//是否需要过滤和排序Lucene.Net.Search.TopDocs topDocs = searcher.Search(query, 100);IList<T> values = new List<T>();//ScoreDoc是得分文档对象foreach (Lucene.Net.Search.ScoreDoc sDoc in topDocs.ScoreDocs){float score = sDoc.Score;//拿到documentLucene.Net.Documents.Document document = reader.Document(sDoc.Doc);values.Add(document.ToEntity<T>());//将document转换成entity}return values;}/// <summary>/// 根据query查询/// </summary>/// <param name="query"></param>private void QueryBySpecidQuery(Lucene.Net.Search.Query query){// 索引搜索工具//IndexSearch可以帮助我们实现:快速搜索、排序、打分等功能。//IndexSearch需要依赖IndexReader类if (query == null) return;if (reader == null) return;Lucene.Net.Search.IndexSearcher searcher = new Lucene.Net.Search.IndexSearcher(reader);if (searcher == null) return;//query的分类//返回100条数据// TopDocs(查询结果对象)//通过IndexSearcher对象,我们可以搜索,获取结果:TopDocs对象Lucene.Net.Search.TopDocs topDocs = searcher.Search(query, 100);//ScoreDoc是得分文档对象foreach (Lucene.Net.Search.ScoreDoc sDoc in topDocs.ScoreDocs){int id = sDoc.Doc;float score = sDoc.Score;//拿到documentLucene.Net.Documents.Document document = reader.Document(id);//将document转换成entity}}//TermQuery可以用“field:key”方式,例如“content:lucene”。//BooleanQuery中‘与’用‘+’,‘或’用‘ ’,例如“content:java contenterl”。//WildcardQuery仍然用‘?’和‘*’,例如“content:use*”。//PhraseQuery用‘~’,例如“content:"中日"~5”。//PrefixQuery用‘*’,例如“中*”。//FuzzyQuery用‘~’,例如“content: wuzza ~”。//RangeQuery用‘[]’或‘{}’,前者表示闭区间,后者表示开区间,例如“time:[20060101 TO 20060130]”,注意TO区分大小写。//例如“标题或正文包括lucene,并且时间在20060101到20060130之间的文章” 可以表示为:“+ (title:lucene content:lucene) +time:[20060101 TO 20060130]”/*#region 特殊查询/// <summary>/// 单条匹配查询/// </summary>public void GetTermQuery(string content){List<string> fids = GetCustomAttributeForQuery<Util.Attributes.TermQueryAttribute>();if (fids != null && fids.Count() > 0){Lucene.Net.Search.Query query = new Lucene.Net.Search.TermQuery(new Lucene.Net.Index.Term(fids[0], content));}}/// <summary>/// 通配符查询/// </summary>public void GetWildcardQuery(string charContent){List<string> fids = GetCustomAttributeForQuery<Util.Attributes.WildcardQueryAttribute>();if (fids != null && fids.Count() > 0){Lucene.Net.Search.Query query = new Lucene.Net.Search.WildcardQuery(new Lucene.Net.Index.Term(fids[0], charContent));}//QueryLucene(query);}/// <summary>/// 模糊查询/// </summary>public void GetFuzzyQuery(string content){List<string> fids = GetCustomAttributeForQuery<Util.Attributes.FuzzyQueryAttribute>();if (fids != null && fids.Count() > 0){Lucene.Net.Search.Query query = new Lucene.Net.Search.FuzzyQuery(new Lucene.Net.Index.Term(fids[0], content));}//QueryLucene(query);}/// <summary>/// 搜索两个单词距离指定间隔的数据/// </summary>public void GetPhraseQuery(int slop, string prv, string next){Lucene.Net.Search.PhraseQuery query = new Lucene.Net.Search.PhraseQuery();query.Slop = 5;query.Add(new Lucene.Net.Index.Term("content ", prv));query.Add(new Lucene.Net.Index.Term("content", next));}/// <summary>/// 以指定字符开头/// </summary>public void GetPrefixQuery(string content){Lucene.Net.Search.PrefixQuery query = new Lucene.Net.Search.PrefixQuery(new Lucene.Net.Index.Term("content ", content));}#endregion*//// <summary>/// 根据传入的特性查找定义了此特性的属性/// </summary>/// <typeparam name="Attr"></typeparam>/// <returns></returns>private static List<string> GetCustomAttributeForQuery<T, Attr>(){var pro = typeof(T).GetProperties().Where(x => x.IsDefined(typeof(Attr), false));var list = pro.Select(x => x?.Name).ToList();return list;// var prop=//return typeof(T).GetProperties().Select(x =>//{//    if (x.IsDefined(typeof(Attr), false))//    {//        return x.Name;//    }//    else//    {//        return null;//    }//}).ToList();}/// <summary>/// 创建组合查询/// </summary>/// <param name="querysAndoccurs">传入需要进行组合的查询方式和逻辑关联</param>/// <returns></returns>public Lucene.Net.Search.Query CreateBooleanQuery(params (Lucene.Net.Search.Query query, Lucene.Net.Search.Occur occur)[] querysAndoccurs){//Lucene.Net.Search.Query query = new Lucene.Net.Search.FuzzyQuery(new Lucene.Net.Index.Term("", ""));//Lucene.Net.Search.Query query2 = Lucene.Net.Search.NumericRangeQuery.NewLongRange("", 0, 0, true, true);Lucene.Net.Search.BooleanQuery bQuery = new Lucene.Net.Search.BooleanQuery();//* 交集:Occur.MUST + Occur.MUST//* 并集:Occur.SHOULD + Occur.SHOULD//* 非:Occur.MUST_NOTquerysAndoccurs.ToList().ForEach(tuple =>{bQuery.Add(tuple.query, tuple.occur);});return bQuery;}/// <summary>/// 创建指定的查询方式。只支持单个查询。/// </summary>/// <typeparam name="U">继承自Query的查询类。如WildcardQuery/PrefixQuery/FuzzyQuery/TermQuery四种等</typeparam>/// <typeparam name="Attr">实体属性上定义的特性名称,表示其需要执行那种查询方式,若有多个则组合成组合查询</typeparam>/// <param name="content">查询关键字</param>/// <returns></returns>public Lucene.Net.Search.Query CreateQuery<T, U, Attr>(string content) where U : Lucene.Net.Search.Query where Attr : Util.Attributes.SpecidQueryAttribute{var tp = typeof(U);var name = tp.Name;//Lucene.Net.Search.Query query1 = new Lucene.Net.Search.TermQuery(new Lucene.Net.Index.Term("", ""));switch (name){case "WildcardQuery":case "PrefixQuery":case "FuzzyQuery":case "TermQuery":return Activator.CreateInstance(typeof(U), new Lucene.Net.Index.Term(GetCustomAttributeForQuery<T,Attr>()[0], content)) as Lucene.Net.Search.Query;}throw new KeyNotFoundException("传入的泛型<U>不正确");}/// <summary>/// 范围查询,包括数字范围或者查询两个字符串指定间隔的数据/// </summary>/// <typeparam name="U"></typeparam>/// <param name="minOrprv">U为long/int/float/double时传入数字,表示范围,为string时传入前边的字符串</param>/// <param name="maxOrnext">U为long/int/float/double时传入数字,表示范围,为string时传入后边的字符串</param>/// <param name="whenString">U为string时传入前后的字符串,这个为两个字符串之间的间隔</param>/// <returns></returns>public Lucene.Net.Search.Query CreateQuery<T, U>(U minOrprv, U maxOrnext, int whenString = 0){Lucene.Net.Search.Query query = null;List<string> fids = GetCustomAttributeForQuery<T, Util.Attributes.NumericRangeQueryAttribute>();if (fids != null && fids.Count() > 0){switch (typeof(U).Name){case "long":case "Int64":query = Lucene.Net.Search.NumericRangeQuery.NewLongRange(fids[0], long.Parse(minOrprv.ToString()), long.Parse(maxOrnext.ToString()), true, true);break;case "int":case "Int32":query = Lucene.Net.Search.NumericRangeQuery.NewIntRange(fids[0], int.Parse(minOrprv.ToString()), int.Parse(maxOrnext.ToString()), true, true);break;case "double":query = Lucene.Net.Search.NumericRangeQuery.NewDoubleRange(fids[0], double.Parse(minOrprv.ToString()), double.Parse(maxOrnext.ToString()), true, true);break;case "float":query = Lucene.Net.Search.NumericRangeQuery.NewFloatRange(fids[0], float.Parse(minOrprv.ToString()), float.Parse(maxOrnext.ToString()), true, true);break;case "string":var pQuery = new Lucene.Net.Search.PhraseQuery();pQuery.Slop = whenString;pQuery.Add(new Lucene.Net.Index.Term(fids[0], minOrprv.ToString()));pQuery.Add(new Lucene.Net.Index.Term(fids[0], maxOrnext.ToString()));query = pQuery;//  query = new Lucene.Net.Search.MultiPhraseQuery();break;default://不允许的throw new InvalidProgramException("传入参数<U>有误,仅允许Long/Float/Double/Int/String");}}return query;}/// <summary>/// 排序方式,如果要使用,需要添加SpecdSortAttribute/// </summary>/// <param name="t"></param>/// <returns></returns>public Lucene.Net.Search.Sort SetSort<T>(T t){//需要拿字段和类型//排序Lucene.Net.Search.Sort sort = new Lucene.Net.Search.Sort(t.GetSortAttributeValue());//排序 哪个前哪个后return sort;}/// <summary>/// 过滤条件/// </summary>/// <returns></returns>public Lucene.Net.Search.Filter SetFilter(){// Lucene.Net.Search.filterreturn Lucene.Net.Search.NumericRangeFilter.NewIntRange("time", 20220112, 20220113, true, true);}}
}

3:扩展方法

public static class ModelExtison{/// <summary>/// 将实体转换成Document/// </summary>/// <typeparam name="T"></typeparam>/// <param name="t"></param>/// <returns></returns>public static Lucene.Net.Documents.Document ToDocument<T>(this T t){Lucene.Net.Documents.Document doc = new Lucene.Net.Documents.Document();foreach (var propertyInfo in t.GetType().GetProperties()){var attr = propertyInfo.GetCustomAttributes(typeof(LuceneCore.Util.Attributes.LuceneDefineAttribute), false);if (attr != null){if (attr.Length > 0){foreach (LuceneCore.Util.Attributes.LuceneDefineAttribute customAttr in attr){doc.Add(new Lucene.Net.Documents.Field(propertyInfo.Name, propertyInfo.GetValue(t) == null ? "" : propertyInfo.GetValue(t).ToString(), customAttr.Store, customAttr.Index));}}else{var attrtmp = new LuceneCore.Util.Attributes.LuceneDefineAttribute();doc.Add(new Lucene.Net.Documents.Field(propertyInfo.Name, propertyInfo.GetValue(t) == null ? "" : propertyInfo.GetValue(t).ToString(), attrtmp.Store, attrtmp.Index));}}}return doc;}/// <summary>/// 将document转换为实体/// </summary>/// <typeparam name="T"></typeparam>/// <param name="document"></param>/// <returns></returns>public static T ToEntity<T>(this Lucene.Net.Documents.Document document){T t = default(T);t = (T)Activator.CreateInstance(typeof(T));foreach (System.Reflection.PropertyInfo pro in typeof(T).GetProperties()){pro.SetValue(t, Convert.ChangeType(document.Get(pro.Name), pro.PropertyType));}return t;}/// <summary>/// 返回标注了指定特性的字段和值/// </summary>/// <typeparam name="T"></typeparam>/// <typeparam name="Attr"></typeparam>/// <param name="obj"></param>/// <returns></returns>public static (string field, string txt) GetCustomAttributeColumn_KeyAndValue<T,Attr>(this T obj){foreach (System.Reflection.PropertyInfo pro in typeof(T).GetProperties()){if (pro.IsDefined(typeof(Attr), false)){var val = pro.GetValue(pro.Name);return (pro.Name, val == null ? "" : val.ToString());}}return ("", "");}/// <summary>/// 根据标注了排序特性的字段的类型返回排序类型/// </summary>/// <typeparam name="T"></typeparam>/// <param name="obj"></param>/// <returns></returns>public static Lucene.Net.Search.SortField[] GetSortAttributeValue<T>(this T obj){Lucene.Net.Search.SortField[] tuples = null;Dictionary<Lucene.Net.Search.SortField, int> keyValuePairs = new Dictionary<Lucene.Net.Search.SortField, int>();var defindSpecidAttr = typeof(T).GetProperties().Where(x => x.IsDefined(typeof(Util.Attributes.SpecidSortAttribute), true));if (defindSpecidAttr != null && defindSpecidAttr.Count() > 0){int index = 0;foreach (var item in defindSpecidAttr){var attr = (Util.Attributes.SpecidSortAttribute)item.GetCustomAttributes(false).FirstOrDefault(x => x.GetType() == typeof(Util.Attributes.SpecidSortAttribute));Lucene.Net.Search.SortField sortField = new Lucene.Net.Search.SortField(item.Name, item.PropertyType.GetSortFieldType(), attr.Desc);//降序keyValuePairs.Add(sortField, attr.Order);tuples[index] = sortField;index++;}}tuples = keyValuePairs.OrderBy(x => x.Value).Select(x => x.Key).ToArray();// tuples = tuples.OrderBy(x => x.Order);return tuples;}/// <summary>/// 具体根据某一类型返回具体数值/// </summary>/// <param name="t"></param>/// <returns></returns>public static int GetSortFieldType(this Type t){return t switch{_ when t.Name == "Int32" || t.Name == "int" => Lucene.Net.Search.SortField.INT,_ when t.Name == "Int64" || t.Name == "long" => Lucene.Net.Search.SortField.LONG,_ when t.Name == "float" => Lucene.Net.Search.SortField.FLOAT,_ when t.Name == "double" => Lucene.Net.Search.SortField.DOUBLE,_ when t.Name == "string" => Lucene.Net.Search.SortField.STRING,_ when t.Name == "byte" => Lucene.Net.Search.SortField.BYTE,_ when t.Name == "short" || t.Name == "Int16" => Lucene.Net.Search.SortField.SHORT,_ => -1};}public static void GetString<T>(this object t){Console.WriteLine(typeof(T).Name);}}

4:特性

4.1(有具体实现)

//Lucene标注特性[AttributeUsage(AttributeTargets.Property)]class LuceneDefineAttribute : Attribute{public LuceneDefineAttribute(){Store = Lucene.Net.Documents.Field.Store.YES;Index = Lucene.Net.Documents.Field.Index.ANALYZED;}public Lucene.Net.Documents.Field.Store Store { get; set; }public Lucene.Net.Documents.Field.Index Index { get; set; }}//排序特性[System.AttributeUsage(System.AttributeTargets.Property)]internal class SpecidSortAttribute : System.Attribute{public SpecidSortAttribute(){Desc = true;Order = 0;}public bool Desc { get; set; }public int Order { get; set; }}

4.2(无具体实现,只是标注一下有便于反射时使用)

public class SpecidQueryAttribute : Attribute{}
public class TermQueryAttribute : SpecidQueryAttribute{}public class WildcardQueryAttribute : SpecidQueryAttribute{}public class FuzzyQueryAttribute : SpecidQueryAttribute{}public class NumericRangeQueryAttribute : SpecidQueryAttribute{}public class PhraseQueryAttribute : SpecidQueryAttribute{}public class PrefixQueryAttribute : SpecidQueryAttribute{}
class SpecidFilterAttribute:Attribute{}

使用:

public void Test<T>(T t){CreateIndexWriter(@"C:\Users\FanLin\Desktop\index");var list = new List<T>();list.Add(t);CreateIndex(list);QueryByKeyWord<T>("搜索", false, null, 100, null, "NAME");var query1 = CreateQuery<T,Lucene.Net.Search.TermQuery, Util.Attributes.TermQueryAttribute>("搜索");var query = CreateBooleanQuery((query1, Lucene.Net.Search.Occur.SHOULD));QueryBySpecidQuery(query);}

总结:对Lucene一个简单的封装,也让自己了解一下,虽然平时用不到。而且还有什么比抄代码更快乐的呢

本来想把DContext注入进去,使T通用,但是目前能力有限还没有找到好方法。就只能使用泛型了。

参考文档:

http://www.luofenming.com/show.aspx?id=ART2021110700001

https://blog.csdn.net/qq_21137441/article/details/98941178

Lucene+Pangu分词相关推荐

  1. Lucene.net(4.8.0)+PanGu分词器 问题记录一 分词器Analyzer的构造和内部成员ReuseStategy

    前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移.因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3 ...

  2. Pangu分词Lucene.Net搜索使用说明

    首先对Lucene做一个简短的介绍: Lucene不是一个完整的全文检索应用,而是一个用java写的全文索引引擎工具包,它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能. Lucene的作 ...

  3. 当前几个主要的Lucene中文分词器的比较

    http://blog.fulin.org/2009/08/lucene_chinese_analyzer_compare.html 1. 基本介绍: paoding :Lucene中文分词" ...

  4. 11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较...

    本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...

  5. java lucene 中文分词_Lucene的中文分词器IKAnalyzer

    分词器对英文的支持是非常好的. 一般分词经过的流程: 1)切分关键词 2)去除停用词 3)把英文单词转为小写 但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好. 国人林良益写的IK Ana ...

  6. 转 Lucene中文分词组件 JE-Analysis 1.5.1 天狼

    2006-05-29 17:40     主题:  [发布]Lucene中文分词组件 JE-Analysis 1.5.1   天狼 注册于: 2006-05-28 00:23 帖子总数: 103 离线 ...

  7. Lucene 中文分词器概述 与 Ik-Analyzer 使用教程

    目录 中文分词器简述 Ik-Analyzer 概述与特性 Ik-Analyzer 下载与使用 创建索引 查询索引 Ik-Analyzer 官方示例源码 中文分词器简述 1.Apache Lucene  ...

  8. 【Lucene】分词器详解,常用的分词器,IKANalyzer

    [Lucene]分词器详解,常用的分词器,IKANalyzer 1. 分词器详解 1.1 分词器的作用 1.2 分词器API 1.2.1 示例 1.2.2 Analyzer 1.2.3 createC ...

  9. 站内搜索——Lucene +盘古分词

    为了方便的学习站内搜索,下面我来演示一个MVC项目. 1.首先在项目中[添加引入]三个程序集和[Dict]文件夹,并新建一个[分词内容存放目录] Lucene.Net.dll.PanGu.dll.Pa ...

  10. 全文检索lucene中文分词的一些总结

    为什么80%的码农都做不了架构师?>>>    全文检索几乎是所有内容管理系统软件(CMS)必备的功能,在对公司的CMS产品的开发维护过程中,全文检索始终是客户重点关注的模块,为满足 ...

最新文章

  1. 教你如何防范远程桌面协议(RDP)的安全威胁
  2. 音乐产业碰撞人工智能,这次擦出了怎样的新火花?
  3. hive 小技巧总结
  4. javaweb学习总结(三十四)——使用JDBC处理MySQL大数据
  5. CodeForces - 1370F2 The Hidden Pair (Hard Version)(交互题+二分)
  6. js与android webview交互
  7. vue 路由按需加载
  8. 多线程控制不同的线程取不同的数据的问题
  9. 文学系列:《红与黑》读书笔记
  10. IBM主机增加“交易实时分析”新能力
  11. ORL Character Recgnition
  12. IDEA 创建工作空间 (空项目) 项目组
  13. SQL Server 数据库之启动 SQL Server 2008 服务
  14. PDF怎么提取图片,这三个方法你肯定不知道
  15. ios开发——图层的新建属性设置和添加
  16. Prometheus监控告警
  17. 从零开始学习VIO笔记 --- 第三讲:基于优化的IMU和视觉信息融合
  18. 金蝶云星空与飞书系统对接方案(飞书审批)
  19. 超详细的KNIME安装教程!
  20. 计【思考】如不解决这些问题,山东招远这类事情以后仍然会不断发生!!

热门文章

  1. FYI|OHBM BrainArt Competition DDL: June06/2021
  2. 计算机系系徽设计说明,系徽设计大赛策划书
  3. 【网络】路由器和交换机区别,什么是网关
  4. 2009英国电子工程学专业排名
  5. 程序员如何看待实力与运气
  6. Android Startup实现分析
  7. 再也不用等待tomcat慢慢下载
  8. 概率论与数理统计学习笔记(3)——Pearson相关系数与Spearman相关系数
  9. 小度加速破圈,智能音箱告别肉搏战
  10. 【UE4】如何获取/下载虚幻4(Unreal Engine4)源码