AND搜索在Lucene .net上返回OR结果

时间:2015-11-12 18:11:04

标签: c# lucene lucene.net

当我搜索'鸡汤'时。我得到的结果包含'鸡','汤'或两者都有。

我尝试了以下搜索查询,它们都返回相同的结果:

  • "chicken"AND"soup"
  • +chicken +soup

以下是我使用的代码,请帮助:

private DataTable SearchDishName(string textSearch)
{
    string MatchingCutomisationIDs = "0"; //There is no Dish with ID zero, this is just to easen the coding.. 
    var ds = new DataSet();
    ds.ReadXml(System.Web.HttpContext.Current.Server.MapPath("~/App_data/MyDataset.xml"));
    DataTable Sample = new DataTable();
    Sample = ds.Tables[0];
    var table = Sample.Clone();
    var Index = createIndex(Sample);
    using (var reader = IndexReader.Open(Index, true))
    using (var searcher = new IndexSearcher(reader))
    {
        using (Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30))
        {
            var queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "DishName", analyzer);
            var collector = TopScoreDocCollector.Create(1000, true);
            try
            {
                var query = queryParser.Parse(textSearch);
                searcher.Search(query, collector);
            }
            catch
            { }
            var matches = collector.TopDocs().ScoreDocs;
            foreach (var item in matches)
            {
                var id = item.Doc;
                var doc = searcher.Doc(id);
                var row = table.NewRow();
                row["CustomisationID"] = doc.GetField("CustomisationID").StringValue;
                table.Rows.Add(row);
            }
        }
    }
    return table;
}

Directory createIndex(DataTable table)
{
    var directory = new RAMDirectory();

    using (Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30))
    using (var writer = new IndexWriter(directory, analyzer, new IndexWriter.MaxFieldLength(1000)))
    {
        foreach (DataRow row in table.Rows)
        {
            var document = new Document();
            document.Add(new Field("DishName", row["YouTubeTitle"].ToString(), Field.Store.YES, Field.Index.ANALYZED));
            document.Add(new Field("CustomisationID", row["CustomisationID"].ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));

            writer.AddDocument(document);
        }

        writer.Optimize();
        writer.Flush(true, true, true);
    }
    return directory;
}

1 个答案:

答案 0 :(得分:0)

您的代码看起来不错,应该可行。我将它重构为一个完整的测试(绿色)。 AND查询的几个不同版本都只返回一个正确的doc。无法看到与您的代码有很大差异。也许你可以看到你把样品切掉的地方有些不同?

[TestClass]
public class UnitTest3
{
    [TestMethod]
    public void TestLucene()
    {
        var writer = CreateIndex();
        AddDish(writer, "chicken soup", "1");
        AddDish(writer, "veg soup", "2");
        AddDish(writer, "chicken balti", "3");
        writer.Flush(true, true, true);
        Assert.AreEqual(3, writer.NumDocs());

        var searcher = new IndexSearcher(writer.GetReader());
        Search(searcher, "chicken AND soup");
        Search(searcher, "\"chicken\" AND \"soup\"");
        Search(searcher, "+chicken +soup");

        writer.Dispose();
    }

    private void Search(IndexSearcher searcher, string query)
    {
        var result = SearchDishName(searcher, query);
        Console.WriteLine(string.Join(", ", result));
        Assert.AreEqual(1, result.Count);
        Assert.AreEqual("1", result[0]);
    }

    private List<string> SearchDishName(IndexSearcher searcher, string textSearch)
    {
        using (var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30))
        {
            var queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "DishName", analyzer);
            var collector = TopScoreDocCollector.Create(1000, true);
            var query = queryParser.Parse(textSearch);
            searcher.Search(query, collector);

            var result = new List<string>();
            var matches = collector.TopDocs().ScoreDocs;
            foreach (var item in matches)
            {
                var id = item.Doc;
                var doc = searcher.Doc(id);
                result.Add(doc.GetField("CustomisationID").StringValue);
            }
            return result;
        }
    }

    IndexWriter CreateIndex()
    {
        var directory = new RAMDirectory();

        var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
        var writer = new IndexWriter(directory, analyzer, new IndexWriter.MaxFieldLength(1000));

        return writer;
    }
    void AddDish(IndexWriter writer, string dishname, string id)
    {
        var document = new Document();
        document.Add(new Field("DishName", dishname, Field.Store.YES, Field.Index.ANALYZED));
        document.Add(new Field("CustomisationID", id, Field.Store.YES, Field.Index.NOT_ANALYZED));

        writer.AddDocument(document);
    }
}