fyj*_*ham 6 c# search lucene.net
我目前正在尝试在大型数据库上实现基于Lucene.NET的搜索,并且我试图搜索基本上是关系数据的问题.
在高级别,我正在尝试搜索的数据被分组,每个项目属于1到3个组.然后,我需要能够搜索组合组中的所有项目(EG:每个项目同时属于组A和组B).
这些分组中的每一个都有我正在搜索的数据中存在的ID和描述,但描述可能是彼此的子字符串(EG:一个名为"Stuff"的组和另一个"其他东西"),我不知道我想匹配具有我正在寻找的子字符串的类别.
我一直在考虑在不进行过滤的情况下将数据拉回来然后过滤ID,但出于性能原因,我打算对从Lucene返回的数据进行分页.我还考虑过将ID放在空格上并在场上进行文本搜索,但这似乎完全是黑客攻击......
有谁知道如何在Lucene.NET中最好地处理这种搜索?(只是在有人说我使用错误的工具之前澄清一下,这只是一组较大的过滤器的一部分,包括全文搜索.如果你仍然认为我使用了错误的工具,虽然我喜欢听听正确的是什么)
我在存储关系数据方面遇到了一些问题我Lucene但是你应该很容易解决这个问题.
我猜你会对组字段进行标记,这样就可以在字段值中搜索子字符串.只需添加未加标记的字段,它应该像预期的那样工作.
请检查以下一小段代码:
internal class Program {
private static void Main(string[] args) {
var directory = new RAMDirectory();
var writer = new IndexWriter(directory, new StandardAnalyzer());
AddDocument(writer, "group", "stuff", Field.Index.UN_TOKENIZED);
AddDocument(writer, "group", "other stuff", Field.Index.UN_TOKENIZED);
writer.Close(true);
var searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(new TermQuery(new Term("group", "stuff")));
for (int i = 0; i < hits.Length(); i++) {
Console.WriteLine(hits.Doc(i).GetField("group").StringValue());
}
}
private static void AddDocument(IndexWriter writer, string name, string value, Field.Index index) {
var document = new Document();
document.Add(new Field(name, value, Field.Store.YES, index));
writer.AddDocument(document);
}
}
Run Code Online (Sandbox Code Playgroud)
该示例将两个文档添加到索引中,这些文档未被标记,搜索内容并获得一个匹配.如果您更改了代码以将其添加为令牌化,那么您现在可以看到两次点击.
将Lucene用于关系数据的问题在于,可能期望通配符和范围搜索始终有效.如果由于Lucene解析这些查询的方式索引很大,情况并非如此.
另一个说明行为的示例:
private static void Main(string[] args) {
var directory = new RAMDirectory();
var writer = new IndexWriter(directory, new StandardAnalyzer());
var documentA = new Document();
documentA.Add(new Field("name", "A", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentA.Add(new Field("group", "stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentA.Add(new Field("group", "other stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(documentA);
var documentB = new Document();
documentB.Add(new Field("name", "B", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentB.Add(new Field("group", "stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(documentB);
var documentC = new Document();
documentC.Add(new Field("name", "C", Field.Store.YES, Field.Index.UN_TOKENIZED));
documentC.Add(new Field("group", "other stuff", Field.Store.YES, Field.Index.UN_TOKENIZED));
writer.AddDocument(documentC);
writer.Close(true);
var query1 = new TermQuery(new Term("group", "stuff"));
SearchAndDisplay("First sample", directory, query1);
var query2 = new TermQuery(new Term("group", "other stuff"));
SearchAndDisplay("Second sample", directory, query2);
var query3 = new BooleanQuery();
query3.Add(new TermQuery(new Term("group", "stuff")), BooleanClause.Occur.MUST);
query3.Add(new TermQuery(new Term("group", "other stuff")), BooleanClause.Occur.MUST);
SearchAndDisplay("Third sample", directory, query3);
}
private static void SearchAndDisplay(string title, Directory directory, Query query3) {
var searcher = new IndexSearcher(directory);
Hits hits = searcher.Search(query3);
Console.WriteLine(title);
for (int i = 0; i < hits.Length(); i++) {
Console.WriteLine(hits.Doc(i).GetField("name").StringValue());
}
}
Run Code Online (Sandbox Code Playgroud)