当在搜索中使用多个单词时,如何在Lucene.net中执行AND搜索?

时间:2011-05-06 22:24:44

标签: c# search lucene lucene.net

我正在和Lucene.net一起试图找到如何在我的应用程序中实现它的方法。

我有以下代码

            .....
            // Add 2 documents
            var doc1 = new Document();
            var doc2 = new Document();

            doc1.Add(new Field("id", "doc1", Field.Store.YES, Field.Index.ANALYZED));
            doc1.Add(new Field("content", "This is my first document", Field.Store.YES, Field.Index.ANALYZED));
            doc2.Add(new Field("id", "doc2", Field.Store.YES, Field.Index.ANALYZED));
            doc2.Add(new Field("content", "The big red fox jumped", Field.Store.YES, Field.Index.ANALYZED));

            writer.AddDocument(doc1);
            writer.AddDocument(doc2);

            writer.Optimize();
            writer.Close();

            // Search for doc2
            var parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "content", new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
            var query = parser.Parse("big abcdefg test1234");
            var searcher = new IndexSearcher(indexDirectory, true);
            var hits = searcher.Search(query);

            Assert.AreEqual(1, hits.Length());

            var document = hits.Doc(0);

            Assert.AreEqual("doc2", document.Get("id"));
            Assert.AreEqual("The big red fox jumped", document.Get("content"));

这个测试通过,让我有点沮丧。我认为这意味着Lucene.Net使用OR来进行术语之间的搜索而不是AND,但是我找不到任何关于如何实际执行AND搜索的信息。

我想要的最终结果是,如果有人搜索“Matthew Anderson”,我不希望它提出涉及“Matthew Doe”的文件,因为这与任何方式,形状或形式无关

2 个答案:

答案 0 :(得分:7)

一个。如果您要求所有单词都在文档中,但不要求单词是连续的并且按照您指定的顺序:查询

+big +red

匹配

* the big red fox jumped
* the red big fox jumped
* the big fast red fox jumped

但不匹配

* the small red fox jumped

B中。如果你想匹配一个短语(即所有需要的单词;单词必须是连续的并且按照指定的顺序)而不是:查询

+"big red"

匹配

* the big red fox jumped

但不匹配

* the red big fox jumped
* the big fast red fox jumped
* the small red fox jumped

答案 1 :(得分:2)

当您的查询为var query = parser.Parse("+big +abcdefg +test1234");时,您会得到什么?这会导致解析器要求所有术语出现在匹配的文档中。另一种可能性是以编程方式构造查询。

BooleanQuery query = new BooleanQuery();
query.add(new BooleanClause(new TermQuery(new Term("field", "big"))), Occur.MUST);
query.add(new BooleanClause(new TermQuery(new Term("field", "abcdefg"))), Occur.MUST);
query.add(new BooleanClause(new TermQuery(new Term("field", "test1234"))), Occur.MUST);