我已经建立了一个Lucene.net书籍索引。一切都运行良好,但我需要添加另一种方法来查询索引,我无法弄清楚如何做到这一点。
基本上每本书的年龄范围都适合。这由两列表示 - minAge和maxAge。两列都是整数。
我正在索引并将这些字段存储在以下循环中
foreach (var catalogueBook in books)
{
var book = new Book(catalogueBook.CatalogueBookNo,catalogueBook.IssueId);
var strTitle = book.FullTitle ?? "";
var strAuthor = book.Author ?? "";
// create a Lucene document for this book
var doc = new Document();
// add the ID as stored but not indexed field, not used to query on
doc.Add(
new Field(
"BookId",
book.CatalogueBookNo.ToString(System.Globalization.CultureInfo.InvariantCulture),
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS,
Field.TermVector.NO));
// add the title and author as stored and tokenized fields, the analyzer processes the content
doc.Add(
new Field("FullTitle",
strTitle.Trim().ToLower(),
Field.Store.YES,
Field.Index.ANALYZED,
Field.TermVector.NO));
doc.Add(
new Field("Author",
strAuthor.Trim().ToLower(),
Field.Store.YES,
Field.Index.ANALYZED,
Field.TermVector.NO));
doc.Add(
new Field("IssueId",
book.IssueId,
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS,
Field.TermVector.NO));
doc.Add(
new Field(
"PublicationId",
book.PublicationId.Trim().ToLower(),
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS,
Field.TermVector.NO));
doc.Add(
new Field(
"MinAge",
book.MinAge.ToString("0000"),
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS,
Field.TermVector.NO));
doc.Add(
new Field(
"MaxAge",
book.MaxAge.ToString("0000"),
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS,
Field.TermVector.NO));
doc.Add(new NumericField("Price",Field.Store.YES,true).SetDoubleValue(Convert.ToDouble(book.Price)));
//Now we can loop through categories
foreach(var bc in book.GetBookCategories())
{
doc.Add(
new Field("CategoryId",
bc.CategoryId.Trim().ToLower(),
Field.Store.YES,
Field.Index.NOT_ANALYZED_NO_NORMS,
Field.TermVector.NO));
}
// add the document to the index
indexWriter.AddDocument(doc);
}
// make lucene fast
indexWriter.Optimize();
}
正如您所看到的那样,我正在填充minAge和maxAge字段,因为我认为对它运行TermRangeQuery最简单。
但是,我需要使用Age查询minAge和maxAge列,以查看Age是否落在minAge和maxAge定义的Age范围内。
Sql将是
Select *
From books
where @age >= minAge and @age <= maxAge
不幸的是我看不到这样做的方法。这在Lucene.Net中甚至可能吗?
答案 0 :(得分:10)
如果内存服务,你应该能够利用范围查询来做到这一点。这实际上是标准范围查询的反转,但您应该能够,例如:
+minAge:[* TO @age] +maxAge:[@age TO *]
或者,如果构造查询对象,则使用上限或下限null的RangeQuery(或更好的NumericRangeQuery)作为开放式范围。
我之前使用过上面的语法,但支持似乎有点......不稳定。如果这不起作用,您可以随时设置一个足够低的下限(0)和上限(例如1000),例如:
+minAge:[0000 TO @age] +maxAge:[@age TO 1000]
哪个应该足够安全,禁止任何Methuselahs。
答案 1 :(得分:4)
在femtoRgon上面的回答的帮助下完成了这个。
var q = new TermRangeQuery("MinAge", "0000",searchTerms.Age.ToString("0000"), true, true);
mainQuery.Add(q, BooleanClause.Occur.MUST);
q = new TermRangeQuery("MaxAge", searchTerms.Age.ToString("0000"),"9999", true, true);
mainQuery.Add(q, BooleanClause.Occur.MUST);
永