【问题标题】:Lucene Search SyntaxLucene 搜索语法
【发布时间】:2014-08-23 18:54:47
【问题描述】:

我需要帮助确定在特定情况下使用哪些查询类型。

我认为我说得对,如果我将“FORD”一词存储在 lucene 字段中并且我想找到完全匹配的内容,我会使用TermQuery

但是,如果我正在寻找“FORD”这个词,该字段的内容存储为:-

“福特|本田|铃木”

如果我要搜索整个页面的内容,寻找一个短语怎么办?比如“请帮帮我”?

【问题讨论】:

    标签: c# search lucene.net


    【解决方案1】:

    如果您想在FORD|HONDA|SUZUKI 中搜索 FORD,可以使用 Field.Index.ANALYZED 进行索引,或者将其存储如下以使用 TermQuery

    var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
    var fs = FSDirectory.Open("test.index");
    
    //Index a Test Document
    IndexWriter wr = new IndexWriter(fs, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);
    var doc = new Document();
    
    doc.Add(new Field("Model", "FORD", Field.Store.YES, Field.Index.NOT_ANALYZED));
    doc.Add(new Field("Model", "HONDA", Field.Store.YES, Field.Index.NOT_ANALYZED));
    doc.Add(new Field("Model", "SUZUKI", Field.Store.YES, Field.Index.NOT_ANALYZED));
    
    doc.Add(new Field("Text", @"What if i was to search the contents of an entire page, looking for a phrase? such as ""please help me""?", 
                        Field.Store.YES, Field.Index.ANALYZED));
    
    wr.AddDocument(doc);
    wr.Commit();
    
    var reader = wr.GetReader();
    var searcher = new IndexSearcher(reader);
    
    //Use TermQuery for "NOT_ANALYZED" fields
    var result = searcher.Search(new TermQuery(new Term("Model", "FORD")), 100);
    foreach (var item in result.ScoreDocs)
    {
        Console.WriteLine("1)" + reader.Document(item.Doc).GetField("Text").StringValue);
    }
    
    //Use QueryParser for "ANALYZED" fields
    var qp = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Text", analyzer);
    result = searcher.Search(qp.Parse(@"""HELP ME"""), 100);
    foreach (var item in result.ScoreDocs)
    {
        Console.WriteLine("2)" + reader.Document(item.Doc).GetField("Text").StringValue);
    }
    

    TermQuery 表示您要搜索存储在索引中的术语,这取决于您对该字段的索引方式(NOT_ANALYZED、ANALYZED+WhichAnalyzer)。它最常见的用途是与 NOT_ANALYZED 字段一起使用。

    您也可以将 TermQueryANALYZED 字段一起使用,但是您应该知道 analyzer 如何标记您的输入字符串。下面是一个示例,看看分析器如何标记您的输入

    var text = @"What if i was to search the contents of an entire page, looking for a phrase? such as ""please help me""?";
    var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30 );
    //var analyzer = new WhitespaceAnalyzer();
    //var analyzer = new KeywordAnalyzer();
    //var analyzer = new SimpleAnalyzer();
    
    var ts = analyzer.TokenStream("", new StringReader(text));
    var termAttr = ts.GetAttribute<ITermAttribute>();
    
    while (ts.IncrementToken())
    {
        Console.Write("[" + termAttr.Term + "] " );    
    }
    

    【讨论】:

    • 非常感谢您!
    • @Derek 大多数时候你必须使用分析的。 NOT_ANALYZED 字段不能与 QueryParser 一起使用(并不总是正确的)。我通常将 NOT_ANALYZED 用于 ID、型号、颜色等字段。如果您想进行类似 google 的搜索(文本中的任何 word ) 使用分析。顺便说一句:Lucene/Lucene.Net 有一个邮件列表,优秀的人可以为您提供更多帮助
    • 是的...(但 QueryParser 不是必须的,您可以使用 BooleanQuery 构建自己的查询。QueryParser 只会自动执行)
    • 感谢您的帮助和耐心等待! :-)
    • @Derek NOT_ANALYZED 的意思是“按原样存储该文本”。所以你必须按原样搜索它(TermQuery)。当我说 as it is 时,我的意思是完全匹配(相同的大写/小写、空格等)。只需在上面的代码中稍微玩一下,看看 Lucene 是如何工作的,然后再继续你的代码。跨度>
    【解决方案2】:

    我会把问题转移到一边,所以我将每个字段的多个值分别放在索引中——这应该会使搜索更简单。查看Field Having Multiple Values 可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-25
      • 2012-10-22
      相关资源
      最近更新 更多