【问题标题】:Lucene query not returning hit on standard analyzerLucene 查询未在标准分析器上返回命中
【发布时间】:2014-07-18 18:48:26
【问题描述】:

我有一个文件名thatfeelwhen.pdf,当我使用“that”或“feel”之类的词进行搜索时,如果我输入“when”或整个文件名,我不会得到任何结果。我正在使用标准分析仪。如何让 Lucene 的搜索器匹配所有内容?我的搜索查询似乎与文件中的内容匹配,但与文件名不匹配。

public partial class _Default : Page
{
    Directory finalDirectory = null;
    Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);

其他方法的代码如下:

private static void AddTextToIndex(string filename, string pdfBody, IndexWriter writer)
    {
        Document doc = new Document();
        doc.Add(new Field("fileName", filename.ToString(), Field.Store.YES, Field.Index.ANALYZED));
        doc.Add(new Field("pdfBody", pdfBody.ToString(), Field.Store.NO, Field.Index.ANALYZED));
        writer.AddDocument(doc);
    }

    private static Directory buildIndex(Analyzer analyzer)
    {
        string[] syllabusFiles = System.IO.Directory.GetFiles(@"C:\mywebsite\files\forms");
        Directory directory = FSDirectory.Open(new DirectoryInfo(@"C:\mywebsite\files\LuceneIndex"));           
        var writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.LIMITED);

        int j = 0;
        while (j < syllabusFiles.Length)
        {
            string pdfTextExtracted = pdfText(syllabusFiles[j]);
            string fileNameOnly = syllabusFiles[j].Replace("C:\\website\\files\\forms", "");
            AddTextToIndex(fileNameOnly, pdfTextExtracted, writer);
            j++;
        }
        writer.Optimize();
        writer.Dispose();
        return directory;
    }

    protected void txtBoxSearchPDF_Click(object sender, EventArgs e)
    {
        if (txtBoxSearchString.Text == "")
        {
            lblNoSearchString.Visible = true;               
        }
        else if (txtBoxSearchString.Text == "build_index")
        {
            this.finalDirectory = buildIndex(this.analyzer);
        }
        else
        {
            //searching PDF text
            lblNoSearchString.Visible = false;
            StringBuilder sb = new StringBuilder();
            this.finalDirectory = FSDirectory.Open(new DirectoryInfo(@"C:\mywebsite\files\LuceneIndex"));
            IndexReader indexReader = IndexReader.Open(this.finalDirectory, true);
            Searcher indexSearch = new IndexSearcher(indexReader);
            string searchQuery = txtBoxSearchString.Text;
            var fields = new[] { "fileName", "pdfBody" };
            var queryParser = new MultiFieldQueryParser(Version.LUCENE_30, fields, this.analyzer);
            Query query;
            try
            {
                query = queryParser.Parse(searchQuery.Trim());
            }
            catch (ParseException)
            {
                query = queryParser.Parse(QueryParser.Escape(searchQuery.Trim()));
            }
            TopDocs resultDocs = indexSearch.Search(query, indexReader.MaxDoc);                

            var hits = resultDocs.ScoreDocs;
            foreach (var hit in hits)
            {
                var documentFromSearcher = indexSearch.Doc(hit.Doc);
                string getResult = documentFromSearcher.Get("fileName");
                string formattedResult = getResult.Replace(" ", "%20");
                sb.AppendLine(@"<a href=https://website.com/search/forms/" + formattedResult+ ">" + getResult+"</a>");
                sb.AppendLine("<br>");
            }

【问题讨论】:

  • 你好像忘记了writer.Commit()
  • 不需要,但感谢您的建议。无论如何,我将它添加到我的代码中。

标签: c# asp.net lucene


【解决方案1】:

我选择使用Analyzer analyzer = new SingleCharTokenAnalyzer(); 并获得了更好的结果。

我尝试了 Simple、Standard、Whitespace 和 Keyword Analyzers,但没有一个能真正满足我的需求,而无需通过创建额外的工作来自定义它们。

【讨论】:

  • 我想我读你的问题有点太快了,没有理解问题...StandardAnalyzer 包括一个停用词删除过滤器(默认设置为:a, an, and, are, as, at, be, but, by, for, if, in, into, is, it, no, not, of, on, or, such, that, the, their, then, there, these, they, this, to, was, will, with)。您可以使用一组空的停用词来实例化 StandardAnalyzer,或者您可以编写一个更适合您需求的分析器,这没什么大不了的。
猜你喜欢
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
  • 2019-06-11
相关资源
最近更新 更多