Lucene.Net]基本用法

AI量化投资开源平台——Qlib(微矿)的学习使用笔记(随缘更新) Qlib 涵盖了量化投资的全过程,为用户的 AI 算法提供了高性能的底层基础架构,从框架设计上让用户可以更容易地应用 AI 算法来辅助解决量化投资的各个关键问题(例如 Alpha 预测,风险预测,市场动态性建模)。本文旨在记录一些面向初学者的基础内容。 阅读详情
本文仅记录一些简单的使用方法,供初学者参考。
以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。

1. 基本应用
using System;
using System.Collections.Generic;
using System.Text;
using Lucene.Net;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Lucene.Net.Util;

namespace ConsoleApplication1.Lucene
{
  public class LuceneTest
  {
    private const string FieldName = "name";
    private const string FieldValue = "value";

    private Directory directory = new RAMDirectory();
    private Analyzer analyzer = new StandardAnalyzer();

    public LuceneTest()
    {
    }

    private void Index()
    {
      IndexWriter writer = new IndexWriter(directory, analyzer, true);
      writer.maxFieldLength = 1000;
      
      for (int i = 1; i <= 100; i++)
      {
        Document document = new Document();

        document.Add(new Field(FieldName, "name" + i, Field.Store.YES, Field.Index.UN_TOKENIZED));
        document.Add(new Field(FieldValue, "Hello, World!", Field.Store.YES, Field.Index.TOKENIZED));

        writer.AddDocument(document);
      }

      writer.Optimize();
      writer.Close();
    }

    private void Search()
    {
      Query query = QueryParser.Parse("name*", FieldName, analyzer);

      IndexSearcher searcher = new IndexSearcher(directory);

      Hits hits = searcher.Search(query);
      
      Console.WriteLine("符合条件记录:{0}; 索引库记录总数:{1}", hits.Length(), searcher.Reader.NumDocs());
      for (int i = 0; i < hits.Length(); i++)
      {
        int docId = hits.Id(i);
        string name = hits.Doc(i).Get(FieldName);
        string value = hits.Doc(i).Get(FieldValue);
        float score = hits.Score(i);

        Console.WriteLine("{0}: DocId:{1}; Name:{2}; Value:{3}; Score:{4}",
          i + 1, docId, name, value, score);
      }

      searcher.Close();
    }
  }
}

除了 RAMDirectory,还可以使用 FSDirectory。(注意 FSDirectory.GetDirectory 的 create 参数,为 true 时将删除已有索引库文件,可以通过 IndexReader.IndexExists() 方法判断。)

从指定目录打开已有索引库。
private Directory directory = FSDirectory.GetDirectory("c:/index", false);

将索引库载入内存,以提高搜索速度。
private Directory directory = new RAMDirectory(FSDirectory.GetDirectory(@"c:/index", false));
//或
//private Directory directory = new RAMDirectory(c:/index");

2. 多字段搜索

使用 MultiFieldQueryParser 可以指定多个搜索字段。
Query query = MultiFieldQueryParser.Parse("name*", new string[] { FieldName, FieldValue }, analyzer);

IndexReader reader = IndexReader.Open(directory);
IndexSearcher searcher = new IndexSearcher(reader);
Hits hits = searcher.Search(query);

3. 多条件搜索

除了使用 QueryParser.Parse 分解复杂的搜索 语法外,还可以通过组合多个 Query 来达到目的。
Query query1 = new TermQuery(new Term(FieldValue, "name1")); // 词语搜索
Query query2 = new WildcardQuery(new Term(FieldName, "name*")); // 通配符
//Query query3 = new PrefixQuery(new Term(FieldName, "name1")); // 字段搜索 Field:Keyword,自动在结尾添加 *
//Query query4 = new RangeQuery(new Term(FieldNumber, NumberTools.LongToString(11L)), new Term(FieldNumber, NumberTools.LongToString(13L)), true); // 范围搜索
//Query query5 = new FilteredQuery(query, filter); // 带过滤条件的搜索
      
BooleanQuery query = new BooleanQuery();
query.Add(query1, BooleanClause.Occur.MUST);
query.Add(query2, BooleanClause.Occur.MUST);

IndexSearcher searcher = new IndexSearcher(reader);
Hits hits = searcher.Search(query);

4. 设置权重

可以给 Document 和 Field 增加权重(Boost),使其在搜索结果排名更加靠前。缺省情况下,搜索结果以 Document.Score 作为排序依据,该数值越大排名越靠前。Boost 缺省值为 1。
Score = Score * Boost

通过上面的公式,我们就可以设置不同的权重来影响排名。

如下面的例子中根据 VIP 级别设定不同的权重。
Document document = new Document();
switch (vip)
{
  case VIP.Gold: document.SetBoost(2F); break;
  case VIP.Argentine: document.SetBoost(1.5F); break;
}

只要 Boost 足够大,那么就可以让某个命中结果永远排第一位,这就是百度等网站的"收费排名"业务。明显有失公平,鄙视一把。 [no]

5. 排序

通过 SortField 的构造参数,我们可以设置排序字段,排序条件,以及倒排。
Sort sort = new Sort(new SortField(FieldName, SortField.DOC, false));

IndexSearcher searcher = new IndexSearcher(reader);
Hits hits = searcher.Search(query, sort);

排序对搜索速度影响还是很大的,尽可能不要使用多个排序条件。

6. 过滤

使用 Filter 对搜索结果进行过滤,可以获得更小范围内更精确的结果。

举个例子,我们搜索上架时间在 2005-10-1 到 2005-10-30 之间的商品。
对于日期时间,我们需要转换一下才能添加到索引库,同时还必须是索引字段。
// index
document.Add(FieldDate, DateField.DateToString(date), Field.Store.YES, Field.Index.UN_TOKENIZED);

//...

// search
Filter filter = new DateFilter(FieldDate, DateTime.Parse("2005-10-1"), DateTime.Parse("2005-10-30"));
Hits hits = searcher.Search(query, filter);

除了日期时间,还可以使用整数。比如搜索价格在 100 ~ 200 之间的商品。
Lucene.Net NumberTools 对于数字进行了补位处理,如果需要使用浮点数可以自己参考源码进行。
// index
document.Add(new Field(FieldNumber, NumberTools.LongToString((long)price), Field.Store.YES, Field.Index.UN_TOKENIZED));

//...

// search
Filter filter = new RangeFilter(FieldNumber, NumberTools.LongToString(100L), NumberTools.LongToString(200L), true, true);
Hits hits = searcher.Search(query, filter);

使用 Query 作为过滤条件。
QueryFilter filter = new QueryFilter(QueryParser.Parse("name2", FieldValue, analyzer));

我们还可以使用 FilteredQuery 进行多条件过滤。
Filter filter = new DateFilter(FieldDate, DateTime.Parse("2005-10-10"), DateTime.Parse("2005-10-15"));
Filter filter2 = new RangeFilter(FieldNumber, NumberTools.LongToString(11L), NumberTools.LongToString(13L), true, true);

Query query = QueryParser.Parse("name*", FieldName, analyzer);
query = new FilteredQuery(query, filter);
query = new FilteredQuery(query, filter2);

IndexSearcher searcher = new IndexSearcher(reader);
Hits hits = searcher.Search(query);

7. 分布搜索

我们可以使用 MultiReader 或 MultiSearcher 搜索多个索引库。
MultiReader reader = new MultiReader(new IndexReader[] { IndexReader.Open(@"c:/index"), IndexReader.Open(@"//server/index") });
IndexSearcher searcher = new IndexSearcher(reader);
Hits hits = searcher.Search(query);


IndexSearcher searcher1 = new IndexSearcher(reader1);
IndexSearcher searcher2 = new IndexSearcher(reader2);
MultiSearcher searcher = new MultiSearcher(new Searchable[] { searcher1, searcher2 });
Hits hits = searcher.Search(query);

还可以使用 ParallelMultiSearcher 进行多线程并行搜索。

8. 合并索引库

将 directory1 合并到 directory2 中。
Directory directory1 = FSDirectory.GetDirectory("index1", false);
Directory directory2 = FSDirectory.GetDirectory("index2", false);

IndexWriter writer = new IndexWriter(directory2, analyzer, false);
writer.AddIndexes(new Directory[] { directory });
Console.WriteLine(writer.DocCount());
writer.Close();

9. 显示搜索语法字符串

我们组合了很多种搜索条件,或许想看看与其对等的搜索语法串是什么样的。
BooleanQuery query = new BooleanQuery();
query.Add(query1, true, false);
query.Add(query2, true, false);
//...

Console.WriteLine("Syntax: {0}", query.ToString());

输出:
Syntax: +(name:name* value:name*) +number:[0000000000000000b TO 0000000000000000d]

呵呵,就这么简单。

10. 操作索引库

删除 (软删除,仅添加了删除标记。调用 IndexWriter.Optimize() 后真正删除。)
IndexReader reader = IndexReader.Open(directory);

// 删除指定序号(DocId)的 Document。
reader.Delete(123);

// 删除包含指定 Term 的 Document。
reader.Delete(new Term(FieldValue, "Hello"));

// 恢复软删除。
reader.UndeleteAll();

reader.Close();

增量更新 (只需将 create 参数设为 false,即可往现有索引库添加新数据。)
Directory directory = FSDirectory.GetDirectory("index", false);
IndexWriter writer = new IndexWriter(directory, analyzer, false);
writer.AddDocument(doc1);
writer.AddDocument(doc2);
writer.Optimize();
writer.Close();

11. 优化

批量向 FSDirectory 增加索引时,增大合并因子(mergeFactor )和最小文档合并数(minMergeDocs)有助于提高性能,减少索引时间。
IndexWriter writer = new IndexWriter(directory, analyzer, true);

writer.maxFieldLength = 1000; // 字段最大长度
writer.mergeFactor = 1000;
writer.minMergeDocs = 1000;

for (int i = 0; i < 10000; i++)
{
  // Add Documentes...
}

writer.Optimize();
writer.Close();

相关参数说明  
STM32H743的ADC还能这么玩?定时器触发+DMA搬运,构建低CPU占用的数据流 本文深入探讨了STM32H743微控制器中ADC的高效使用方法,通过定时器触发和DMA搬运技术实现低CPU占用的数据流采集。详细解析了硬件架构、CubeMX配置步骤及高级优化技巧,包括双缓冲技术和多ADC同步采样,适用于电机控制、音频采集等高性能应用场景。 阅读详情

相关推荐

lucene 权重设置

对权重设置 已经查询时进行了描述 可以作为参考

lucene7.6.0中文分词+权重设置

最近项目需要使用到中文分词,所以想到了使用lucene+ik分词来实现。 使用技术为 lucene7.6.0

weixin_46422238的博客 1018

ISO IEC 27040 -2024 Information technology - Security techniques - Storage security.pdf

ISO IEC 27040 -2024 Information technology - Security techniques - Storage security.pdf

探究Lucene计算权重的过程

探究Lucene计算权重的过程 我们知道,影响一个词在一篇文档中的重要性主要有两个因素: 1 term frequency (tf):该词在当前文档出现了多少次,tf越大,说明越重要。 2 document frequency (df):有多少文档包含该term,该词越大说明太普通了,越不重要。 比如solr一词在文档中出现次数很多,说明这篇这篇文档主要是跟solr有关的;

happy19870612's blog 4578

从零开始搭建.NET Core版搜索引擎(一)--Lucene基础概念及示例

近期使用了ELK系列组件,不由的感慨其功能的丰富和强大,伴随而来的就是另一个想法“ELK太重,用在简单的小型项目上有些鸡肋,能不能做一个轻量版的搜索引擎用于微小型项目呢?”。 下面将会有一系列的文章来描述整个过程,每篇不会太长,但每篇相比前篇都会有所改进。

lordwish的专栏 3716

lucene - lucene8.7.0 如何一次性搜索多个域并配置权重及分析器

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。 问 :如何实现多域搜索? 答 :使用 MultiFieldQueryParser public void articleSearchServiceTest() throws ParseException { ArticleSearchService articleSearchService = ServiceBindCache.getBean(ArticleSearchService.clas.

我的博客 837

[转][Lucene.Net] 基本用法

原文地址:http://www.rainsts.net/article.asp?id=313 [Lucene.Net基本用法 本文仅记录一些简单的使用方法,供初学者参考。 以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。 1. 基本应用 using System; using System.Collections.Generic; u...

weixin_33717117的博客 120

Lucene.NET 1.9 基本用法

Lucene.NET 1.9 基本用法本文仅记录一些简单的使用方法,供初学者参考。 以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。 1. 基本应用 using System; using System.Collections.Generic; using System.Text; using Lucene.Net; using Lucene.Net.An

sgear 1040

[Lucene.Net] 基本用法

本文仅记录一些简单的使用方法,供初学者参考。以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。1. 基本应用using System;using System.Collections.Generic;using System.Text;using Lucene.Net;using Lucene.Net.Analysis;usi

canduecho的专栏 703

Lucene.Net] 基本用法

本文仅记录一些简单的使用方法,供初学者参考。以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。1. 基本应用using System;using System.Collections.Generic;using System.Text;using Lucene.Net;using Lucene.Net.Analysis;using Lucene.Net.An

xwchen的专栏 856

Lucene.Net基本用法

本文仅记录一些简单的使用方法,供初学者参考。以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。1. 基本应用using System;using System.Collections.Generic;using System.Text;using Lucene.Net;using Lucene.Net.Analysis;using Lucene.Net.An

joe_coor的专栏 550

Lucene.Net 基本用法

本文仅记录一些简单的使用方法,供初学者参考。以下例子采用 Lucene.NET 1.9 版本,可取去 Lucene.Net 下载。1. 基本应用using System;using System.Collections.Generic;using System.Text;using Lucene.Net;using Lucene.Net.Analysis;using Lucene.Net...

weixin_30607029的博客 117

Lucene3.0结果排序原理+操作+示例

Lucene3.0之结果排序(原理篇) 传统上,人们将信息检索系统返回结果的排序称为"相关排序" (relevance ranking) ,隐含其中各条目的顺序反映结果和查询的相关程度。 1、 基本排序原理 ①     向量空间模型 Gerald Salton 等在 30 多年前提出的"向量空间模型" (Vector Space Model,VSM)[Salton and Lesk,19...

weixin_33694172的博客 385

使用Lucene.Net做一个简单的搜索引擎-全文索引

Lucene.Net Lucene.netLucene.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。 Lucene.net是Apache软件基金会赞助的开源项目,基于Apache License协议。 Lucene.net并不是一个爬行搜索引擎,也不会自动地索引内容。我们得先将要索引的文档中的文本抽取出来,然后再将其加到Lucene.net索引中。标准的步骤是先初始化一个Analyzer、打开一个Index.

rizon886的博客 885

Lucene.NET全文搜索详细使用与详解

1. lucene简介 1.1 什么是lucenepowered by 25175.net Lucene是一个全文搜索框架,而不是应用产品。因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品。 1.2 lucene能做什么 要回答这个问题,先要了解lucene的本质。实际上lucene的功能很单一,说到底,就是你给它若干个...

老陈聊架构 1774

Lucene.net站内搜索2—Lucene.Net简介和分词

Lucene.Net简介 Lucene.Net是由Java版本的Lucene(卢思银)移植过来的,所有的类、方法都几乎和Lucene一模一样,因此使用时参考Lucene 即可。Lucene.Net只是一个全文检索开发包(就像ADO.Net和管理系统的关系),不是一个成型的搜索引擎,它的功能就是:把数据扔给Lucene.Net ,查询数据的时候从Lucene.Net 查询数据,可以看做是提供了全文

邹玉杰(邹琼俊)的专栏 5394

使用Lucene.Net实现全文检索

目录 一Lucene.Net概述 二 分词 三 索引 四 搜索 五 实践中的问题 一Lucene.Net概述   Lucene.Net是一个C#开发的开源全文索引库,其源码包括“核心”与“外围”两部分。外围部分实现辅助功能,而核心部分包括: Lucene.Net.Index 提供索引管理,词组排序。Lucene.Net.Search 提供查询相关功能。Luce

李赛赛的专栏 1万+

lucene.net全文检索简介

lucene.net.Net下的全文检索的工具包,不是应用,只是个类库,完成了全文检索的功能;预先把数据拆分成原子(字/词),保存到磁盘中;查询时把关键字也拆分成原子(字/词),再根据(字/词)进行匹配,返回结果。 Nuget安装“Lucene.Net”和“Lucene.Net.Analysis.PanGu”(盘古分词,一个第三方的分词器) 一、lucene.net七大对象 1、Analysis:分词器,负责把字符串拆分成原子,包含了标准分词,直接空格拆分。项目中用的是盘古中文分词, 2、Docum

qq_26900081的博客 2105
上一篇: 深入 Lucene 索引机制
下一篇: 中文搜索引擎技术揭密:网络蜘蛛
wangkun9999
博客等级 码龄20年 881粉丝 6原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值