1. TermQuery
查询某个特定的词,在文章开始的例子中已有介绍.常用于查询关键字.
[Test]
public void Keyword()
{
IndexSearcher searcher = new IndexSearcher(directory);
Term t = new Term("isbn", "1930110995");
Query query = new TermQuery(t);
Hits hits = searcher.Search(query);
Assert.AreEqual(1, hits.Length(), "JUnit in Action");
}
注意Lucene中的关键字,是需要用户去保证唯一性的.
TermQuery和QueryParse
只要在QueryParse的Parse方法中只有一个word,就会自动转换成TermQuery.
2. RangeQuery
用于查询范围,通常用于时间,还是来看例子:
namespace dotLucene.inAction.BasicSearch
{
public class RangeQueryTest : LiaTestCase
{
private Term begin, end;
[SetUp]
protected override void Init()
{
begin = new Term("pubmonth", "200004");
end = new Term("pubmonth", "200206");
base.Init();
}
[Test]
public void Inclusive()
{
RangeQuery query = new RangeQuery(begin, end, true);
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
Assert.AreEqual(1, hits.Length());
}
[Test]
public void Exclusive()
{
RangeQuery query = new RangeQuery(begin, end, false);
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
Assert.AreEqual(0, hits.Length());
}
}
}
RangeQuery的第三个参数用于表示是否包含该起止日期.
RangeQuery和QueryParse
[Test]
public void TestQueryParser()
{
Query query = QueryParser.Parse("pubmonth:[200004 TO 200206]", "subject", new SimpleAnalyzer());
Assert.IsTrue(query is RangeQuery);
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
query = QueryParser.Parse("{200004 TO 200206}", "pubmonth", new SimpleAnalyzer());
hits = searcher.Search(query);
Assert.AreEqual(0, hits.Length(), "JDwA in 200206");
}
Lucene用[] 和{}分别表示包含和不包含.
3. PrefixQuery
用于搜索是否包含某个特定前缀,常用于Catalog的检索.
[Test]
public void TestPrefixQuery()
{
PrefixQuery query = new PrefixQuery(new Term("category", "/Computers"));
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
Assert.AreEqual(2, hits.Length());
query = new PrefixQuery(new Term("category", "/Computers/JUnit"));
hits = searcher.Search(query);
Assert.AreEqual(1, hits.Length(), "JUnit in Action");
}
PrefixQuery和QueryParse
[Test]
public void TestQueryParser()
{
QueryParser qp = new QueryParser("category", new SimpleAnalyzer());
qp.SetLowercaseWildcardTerms(false);
Query query =qp.Parse("/Computers*");
Console.Out.WriteLine("query = {0}", query.ToString());
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
Assert.AreEqual(2, hits.Length());
query =qp.Parse("/Computers/JUnit*");
hits = searcher.Search(query);
Assert.AreEqual(1, hits.Length(), "JUnit in Action");
}
这里需要注意的是我们使用了QueryParser对象,而不是QueryParser类. 原因在于使用对象可以对QueryParser的一些默认属性进行修改.比如在上面的例子中我们的category是大写的,而QueryParser默认会把所有的含*的查询字符串变成小写/computer*. 这样我们就会查不到原文中的/Computers* ,所以我们需要通过设置QueryParser的默认属性来改变这一默认选项.即qp.SetLowercaseWildcardTerms(false)所做的工作.
4. BooleanQuery
用于测试满足多个条件.
下面两个例子用于分别测试了满足与条件和或条件的情况.
[Test]
public void And()
{
TermQuery searchingBooks =
new TermQuery(new Term("subject", "junit"));
RangeQuery currentBooks =
new RangeQuery(new Term("pubmonth", "200301"),
new Term("pubmonth", "200312"),
true);
BooleanQuery currentSearchingBooks = new BooleanQuery();
currentSearchingBooks.Add(searchingBooks, true, false);
currentSearchingBooks.Add(currentBooks, true, false);
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(currentSearchingBooks);
AssertHitsIncludeTitle(hits, "JUnit in Action");
}
[Test]
public void Or()
{
TermQuery methodologyBooks = new TermQuery(
new Term("category",
"/Computers/JUnit"));
TermQuery easternPhilosophyBooks = new TermQuery(
new Term("category",
"/Computers/Ant"));
BooleanQuery enlightenmentBooks = new BooleanQuery();
enlightenmentBooks.Add(methodologyBooks, false, false);
enlightenmentBooks.Add(easternPhilosophyBooks, false, false);
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(enlightenmentBooks);
Console.Out.WriteLine("or = " + enlightenmentBooks);
AssertHitsIncludeTitle(hits, "Java Development with Ant");
AssertHitsIncludeTitle(hits, "JUnit in Action");
}
什么时候是与什么时候又是或? 关键在于BooleanQuery对象的Add方法的参数.
参数一是待添加的查询条件.
参数二Required表示这个条件必须满足吗? True表示必须满足, False表示可以不满足该条件.
参数三Prohibited表示这个条件必须拒绝吗? True表示这么满足这个条件的结果要排除, False表示可以满足该条件.
这样会有三种组合情况,如下表所示:
BooleanQuery和QueryParse
[Test]
public void TestQueryParser()
{
Query query = QueryParser.Parse("pubmonth:[200301 TO 200312] AND junit", "subject", new SimpleAnalyzer());
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
Assert.AreEqual(1, hits.Length());
query = QueryParser.Parse("/Computers/JUnit OR /Computers/Ant", "category", new WhitespaceAnalyzer());
hits = searcher.Search(query);
Assert.AreEqual(2, hits.Length());
}
注意AND和OR的大小 如果想要A与非B 就用 A AND –B 表示, +A –B也可以.
默认的情况下QueryParser会把空格认为是或关系,就象google一样.但是你可以通过QueryParser对象修改这一属性.
[Test]
public void TestQueryParserDefaultAND()
{
QueryParser qp = new QueryParser("subject", new SimpleAnalyzer());
qp.SetOperator(QueryParser.DEFAULT_OPERATOR_AND );
Query query = qp.Parse("pubmonth:[200301 TO 200312] junit");
IndexSearcher searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query);
Assert.AreEqual(1, hits.Length());
}
5. PhraseQuery
查询短语,这里面主要有一个slop的概念, 也就是各个词之间的位移偏差, 这个值会影响到结果的评分.如果slop为0,当然最匹配.看看下面的例子就比较容易明白了,有关slop的计算用户就不需要理解了,不过slop太大的时候对查询效率是有影响的,所以在实际使用中要把该值设小一点. PhraseQuery对于短语的顺序是不管的,这点在查询时除了提高命中率外,也会对性能产生很大的影响, 利用SpanNearQuery可以对短语的顺序进行控制,提高性能.
[SetUp]
protected void Init()
{
// set up sample document
RAMDirectory directory = new RAMDirectory();
IndexWriter writer = new IndexWriter(directory,
new WhitespaceAnalyzer(), true);
Document doc = new Document();
doc.Add(Field.Text("field",
"the quick brown fox jumped over the lazy dog"));
writer.AddDocument(doc);
writer.Close();
searcher = new IndexSearcher(directory);
}
private bool matched(String[] phrase, int slop)
{
PhraseQuery query = new PhraseQuery();
query.SetSlop(slop);
for (int i = 0; i < phrase.Length; i++)
{
query.Add(new Term("field", phrase[i]));
}
Hits hits = searcher.Search(query);
return hits.Length() > 0;
}
[Test]
public void SlopComparison()
{
String[] phrase = new String[]{"quick", "fox"};
Assert.IsFalse(matched(phrase, 0), "exact phrase not found");
Assert.IsTrue(matched(phrase, 1), "close enough");
}
[Test]
public void Reverse()
{
String[] phrase = new String[] {"fox", "quick"};
Assert.IsFalse(matched(phrase, 2), "exact phrase not found");
Assert.IsTrue(matched(phrase, 3), "close enough");
}
[Test]
public void Multiple()-
{
Assert.IsFalse(matched(new String[] {"quick", "jumped", "lazy"}, 3), "not close enough");
Assert.IsTrue(matched(new String[] {"quick", "jumped", "lazy"}, 4), "just enough");
Assert.IsFalse(matched(new String[] {"lazy", "jumped", "quick"}, 7), "almost but not quite");
Assert.IsTrue(matched(new String[] {"lazy", "jumped", "quick"},
, "bingo");
}
PhraseQuery和QueryParse
利用QueryParse进行短语查询的时候要先设定slop的值,有两种方式如下所示
[Test]
public void TestQueryParser()
{
Query q1 = QueryParser.Parse(""quick fox"",
"field", new SimpleAnalyzer());
Hits hits1 = searcher.Search(q1);
Assert.AreEqual(hits1.Length(), 0);
Query q2 = QueryParser.Parse(""quick fox"~1", //第一种方式
"field", new SimpleAnalyzer());
Hits hits2 = searcher.Search(q2);
Assert.AreEqual(hits2.Length(), 1);
QueryParser qp = new QueryParser("field", new SimpleAnalyzer());
qp.SetPhraseSlop(1); //第二种方式
Query q3=qp.Parse(""quick fox"");
Assert.AreEqual(""quick fox"~1", q3.ToString("field"),"sloppy, implicitly");
Hits hits3 = searcher.Search(q2);
Assert.AreEqual(hits3.Length(), 1);
}
6. WildcardQuery
通配符搜索,需要注意的是child, mildew的分值是一样的.
[Test]
public void Wildcard()
{
IndexSingleFieldDocs(new Field[]
{
Field.Text("contents", "wild"),
Field.Text("contents", "child"),
Field.Text("contents", "mild"),
Field.Text("contents", "mildew")
});
IndexSearcher searcher = new IndexSearcher(directory);
Query query = new WildcardQuery(
new Term("contents", "?ild*"));
Hits hits = searcher.Search(query);
Assert.AreEqual(3, hits.Length(), "child no match");
Assert.AreEqual(hits.Score(0), hits.Score(1), 0.0, "score the same");
Assert.AreEqual(hits.Score(1), hits.Score(2), 0.0, "score the same");
}
WildcardQuery和QueryParse
需要注意的是出于性能的考虑使用QueryParse的时候,不允许在开头就使用就使用通配符.
同样处于性能考虑会将只在末尾含有*的查询词转换为PrefixQuery.
[Test, ExpectedException(typeof (ParseException))]
public void TestQueryParserException()
{
Query query = QueryParser.Parse("?ild*", "contents", new WhitespaceAnalyzer());
}
[Test]
public void TestQueryParserTailAsterrisk()
{
Query query = QueryParser.Parse("mild*", "contents", new WhitespaceAnalyzer());
Assert.IsTrue(query is PrefixQuery);
Assert.IsFalse(query is WildcardQuery);
}
[Test]
public void TestQueryParser()
{
Query query = QueryParser.Parse("mi?d*", "contents", new WhitespaceAnalyzer());
Hits hits = searcher.Search(query);
Assert.AreEqual(2, hits.Length());
}
7. FuQuery
模糊查询, 需要注意的是两个匹配项的分值是不同的,这点和WildcardQuery是不同的
[Test]
public void Fu()
{
Query query = new FuQuery(new Term("contents", "wuzza"));
Hits hits = searcher.Search(query);
Assert.AreEqual( 2, hits.Length(),"both close enough");
Assert.IsTrue(hits.Score(0) != hits.Score(1),"wu closer than fu");
Assert.AreEqual("wu", hits.Doc(0).Get("contents"),"wuzza bear");
}
FuQuery和QueryParse
注意和PhraseQuery中表示slop的区别,前者~后要跟数字.
[Test]
public void TestQueryParser()
{
Query query =QueryParser.Parse("wuzza~","contents",new SimpleAnalyzer());
Hits hits = searcher.Search(query);
Assert.AreEqual( 2, hits.Length(),"both close enough");
}
分享到:
相关推荐
Lucene.NET 2.0 API是这个开源项目的特定版本,它在.NET平台上实现了Lucene的功能,让.NET开发者可以轻松地在应用程序中集成强大的搜索引擎。 Lucene.NET的核心功能包括: 1. **索引创建与更新**:Lucene.NET允许...
《深入理解Lucene.Net 2.0:源码与文档解析》 Lucene.Net是一个开源的全文搜索引擎库,它是Apache Lucene项目在.NET平台上的实现,由DotLucene发展而来,广泛应用于各种信息检索和文本挖掘场景。这个资料包包含了...
在Lucene.Net 2.0中,这些功能被封装在易于使用的API中,使得开发人员能够快速集成全文搜索到他们的应用中。 二、索引构建 在Lucene.Net中,索引是通过Analyzer、Document和Field三个关键组件构建的。Analyzer负责...
《深入剖析Lucene.NET 2.0:打造高效全文搜索引擎》 Lucene.NET 2.0 是一个基于 Apache Lucene 的开源全文检索库,专为 .NET Framework 设计。它提供了一种强大而灵活的方式来在应用程序中实现全文搜索功能,支持...
Lucene.Net 2.0 已编译 dll
下面我们将深入探讨Lucene.Net 2.0的主要特性和使用方法。 **1. 全文搜索功能** Lucene.Net的核心就是强大的全文检索能力。它能够对文本进行分词,并建立索引,从而实现快速的关键词查找。在ASP.NET应用中,这使得...
标题中的“vb.net2.0_Lucene_test.rar_lucene_lucene vb.n_lucene.net vb”表明这是一个关于使用VB.NET 2.0版本实现Lucene搜索引擎的测试项目。Lucene是一个高性能、全文本搜索库,广泛应用于Java开发,而这里则是将...
在Lucene.NET中,高亮显示搜索结果是一项常用功能,它可以帮助用户快速定位搜索关键词。高亮通常通过Highlighter类实现,以下是一般流程: 1. **创建Highlighter实例**:`var highlighter = new ...
ASP.NET 2.0 是微软开发的一个用于构建Web应用程序的框架,它在.NET Framework 2.0版本中推出,提供了丰富的特性和工具,使得开发者能够更高效地构建动态网站、Web服务以及Web应用程序。本项目案例导航涵盖了多个...
Lucene.Net 2.0 版本提供了强大的搜索功能,使得开发者能够轻松地在大量数据中进行高效的文本检索。这个类MSDN操作文档包含了对 Lucene.Net 2.0 的详细说明,帮助开发者理解和使用其丰富的特性和功能。 ### Lucene...
在Lucene.NET中,我们可以使用`IndexWriter`的`DeleteDocuments`方法来删除文档,然后再次添加。 ```csharp // 删除匹配特定条件的文档 indexWriter.DeleteDocuments(new TermQuery(new Term("id", "document_id"))...
这个压缩包中的源码包含了Lucene.Net 2.0的完整开发源码,开发者可以通过阅读源码学习其内部实现,理解搜索引擎的工作原理,或者对源码进行修改和扩展,以适应特定的项目需求。由于这是一个较早的版本,可能不包含...
基于Lucene.net的四个版本(更新至2018.1.26 ) ...Lucene.Net.2.9.2.2-支持.net2.0和4.0; Lucene.Net.2.9.4.1 仅支持.net4.0; Lucene.Net.3.0.3 z支持3.5和4.0; Lucene.Net.4.8.0-beta00005支持.net4.5;
本文将详细介绍Lucene.Net的基本用法,包括环境搭建、基本应用流程(索引创建与文档搜索)、多字段搜索以及一些高级特性。 #### 二、环境搭建 在使用Lucene.Net之前,需确保已安装.NET Framework或.NET Core环境,...
除了基本的搜索功能,Lucene.net还提供了如高亮显示搜索结果、地理位置搜索、评分排序等功能。开发者可以根据需求通过扩展Lucene.net的功能来满足特定场景的应用。 **七、实战案例** 学习文档中可能包含了一些实际...
**Lucene.Net** 是一个基于Java的全文搜索引擎库,它被移植到了.NET平台,为.NET开发者提供了强大的文本搜索功能。这个库是开源的,由Apache软件基金会维护,遵循Apache许可证,允许开发人员自由使用和修改代码。 ...
在Lucene.Net中,分析器(Analyzer)是处理文本输入的关键部分,它负责将原始文本分解为搜索时使用的独立词项(Tokens)。对于中文来说,由于词与词之间没有明显的分隔符,所以需要特殊的分析器来完成分词工作。...
4. **创建Document**:Document是Lucene.Net中的基本数据结构,代表一个要索引的文档。添加字段(Field)来存储文档内容,如标题、内容等。 5. **索引文档**:使用IndexWriter将Document写入索引。 6. **关闭资源**...
5. 集成应用:将Lucene.NET集成到ASP.NET、WPF、WinForms等.NET应用程序中,实现全站搜索。 五、未来发展趋势 虽然目前最新的Lucene.NET版本已经更新至4.x,但2.9.1版本仍有其价值,尤其对于维护旧项目的开发者。...
Apache Lucene.Net是一个高度成熟且广泛使用的全文搜索引擎库,它基于Java的Apache Lucene项目,但完全用C#重写,以适应.NET Framework。这个压缩包"Incubating-Apache-Lucene.Net-2.0-004-11Mar07.bin.zip"包含了...