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 足够大,那么就可以让某个命中结果永远排第一位,这就是百度等网站的”收费排名”业务。明显有失公平,鄙视一把。
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();
分享到:
相关推荐
Lucene 排序、设置权重、优化、分布式搜索 Lucene 是一个高性能的搜索引擎库,它提供了强大的文本搜索和索引能力。下面我们将详细介绍 Lucene 的排序、设置权重、优化和分布式搜索等知识点。 一、Lucene 排序 ...
虽然Lucene本身是一个库,但有许多基于Lucene的框架和工具,如Solr和Elasticsearch,它们提供了更高级的功能,如分布式搜索、自动完成、多语言支持等。 7. **搜索引擎实例** "lucene搜索引擎项目"可能包含了从零...
9. **分布式搜索**:虽然3.0.3版本可能不包含完整的分布式搜索解决方案,但你可以了解Lucene如何为大型数据集提供支持,以及后续版本中引入的Solr或Elasticsearch如何解决这一问题。 10. **扩展性**:Lucene的API...
Apache Solr和Elasticsearch提供了分布式搜索解决方案,它们基于Lucene,能处理大规模的数据和高并发请求。 8. **实时索引**:在动态更新内容的场景下,我们需要实时或准实时地更新索引。Lucene支持添加、删除和...
Solr和Elasticsearch是在Lucene基础上构建的分布式搜索平台,它们提供集群管理和负载均衡,能处理PB级别的数据,并支持复杂的查询和聚合操作。 六、扩展应用 1. ** autocomplete**:利用Lucene的PrefixQuery或...
在论文中,作者可能详细介绍了如何利用Lucene的API对职位信息进行建索引,包括字段划分、分词处理、权重计算等步骤,以确保搜索结果的相关性和精度。 其次,Heritrix是一个网络爬虫框架,用于抓取互联网上的网页...
4. **分布式搜索(Distributed Searching)**: 通过 Solr 或 Elasticsearch 等项目,Lucene 可以扩展到分布式环境中,支持大规模的数据和高并发访问。 5. **更新与删除(Updating & Deleting)**: Lucene 支持对已...
7. **分布式搜索**:随着数据量的增大,单机索引可能无法满足需求,因此需要了解如何利用Solr或Elasticsearch等基于Lucene的分布式搜索解决方案。 8. **性能优化**:这部分可能涵盖索引和查询性能的优化策略,如...
对于大型数据集,Lucene支持Solr和Elasticsearch这样的分布式搜索平台,它们在Lucene的基础上提供了集群管理和分布式索引、搜索能力。 8. **错误处理与调试** 官方文档中还包含了许多错误处理和调试技巧,帮助...
2. **多字段搜索(Multi-Field Search)**: 用户可以同时在多个字段上进行搜索,Lucene 4.6.0 对此提供了支持,并且允许设置不同字段的权重。 3. **复杂查询支持(Advanced Query Support)**: 包括短语查询、布尔...
通过设置MultiFieldQueryParser,可以指定哪些字段参与搜索,并控制不同字段的权重。 五、高亮显示 为了帮助用户快速定位到搜索结果中的匹配部分,Lucene提供了Highlighter组件,它可以将匹配的关键词在搜索结果中...
- 分片与分布式:大型应用中,可以利用Sharding或Solr/Lucene Cloud实现分布式搜索。 - 索引优化:定期重建索引以提高搜索性能,避免过度碎片化。 - 内存管理:合理配置缓存,避免内存溢出。 总结,Lucene 3.5.0...
它们在Lucene之上提供了更高级的功能,如分布式搜索、集群管理、更多数据源支持等。 10. **优化与维护** Lucene提供了合并段(Merge)和优化索引(Optimize)的功能,以减少索引碎片,提高搜索性能。同时,定期...
- **分布式搜索**:当数据量庞大时,可以使用Lucene的Solr或Elasticsearch进行分布式搜索,提高性能和可扩展性。 - **缓存策略**:为了提升用户体验,可以考虑对热门查询结果进行缓存。 - **查询优化**:通过分析...
Lucene是一个库,而非完整的搜索引擎产品,因此通常与其他技术结合使用,如Solr(提供REST接口和集群功能)或Elasticsearch(分布式搜索引擎)。5.2.1版本可以轻松地与这些框架集成,实现更复杂的应用场景。 9. **...
- **Solr**:基于Lucene的企业级搜索平台,提供了更完善的管理、集群和分布式搜索功能。 - **Elasticsearch**:也是基于Lucene,提供了分布式、RESTful风格的搜索和分析引擎。 - **Spring Data**:与Spring框架的...
**正文** Lucene是一款强大的全文搜索...同时,Lucene也提供了丰富的API,便于与其他系统集成,如Solr和Elasticsearch等,这些基于Lucene的高级搜索服务提供了更多功能,如分布式搜索、集群管理和更复杂的查询语法。
5. **评分机制(Scoring)**:Lucene通过TF-IDF算法和其他相关性计算方法,为搜索结果排序,最相关的文档优先展示。 6. **内存缓存与磁盘存储**:Lucene优化了内存和磁盘的使用,允许快速读取索引,同时保持索引的...
- **分布式搜索**:通过Solr或Elasticsearch等扩展,可以实现跨服务器的分布式搜索,处理大规模数据。 4. **应用场景** - **企业级搜索**:在企业内部网、文档管理系统中,用于快速查找相关信息。 - **电子...