2

私はさまざまなフレーズを含むインデックス ストアを持っていますが、スペルが間違っているものもあります。

"Hallo World"
"Qick Brown Fox"
"Long tame no sees"

ブールクエリを使用してあいまい検索を実行していますが、一致した場合、一致したフレーズを取得する方法がわかりません。簡単に手に入るインデックスストアのフレーズだけが欲しいわけではありません。

たとえば、検索が ("Hello World" または "Keep it Real" または "Long Time no See") のブールクエリである場合、"Hallo World" および "Long tame no sees" が返されます。ただし、元のフレーズ「Hello World」と「Long Time no See」が一致したことも知っておく必要があります。何か案は?私の検索方法は次のとおりです(現在、フレーズ一致を返しますが、スペルミスのものを返します):-

public IEnumerable<DocumentWrapper> Search(List<string> fieldsToSearch, List<string> phrases, string path)
{

    var luceneDir = FSDirectory.Open(new DirectoryInfo(path));

    if (luceneDir == null)
    {
        Logging.Error("Invalid Index Directory during Search");
        return null;
    }
    Logging.Information(string.Format("Searching for phrase(s): {0}", phrases.ToSeparatedList()));


    var analyzer = new StandardAnalyzer(Version.LUCENE_30);
    IndexReader indexReader;
    try
    {
        indexReader = IndexReader.Open(luceneDir, true);
    }
    catch (FileNotFoundException)
    {
        Logging.Error("Lucene Directory has no items");
        return null;
    }


    var matchedDocuments = new List<DocumentWrapper>();
    try
    {
        var searcher = new IndexSearcher(indexReader);
        MultiFieldQueryParser queryParser = null;
        if (fieldsToSearch != null)
        {
            queryParser = new MultiFieldQueryParser(Version.LUCENE_30, fieldsToSearch.ToArray(), analyzer);
        }
        else
        {
            queryParser = new MultiFieldQueryParser(Version.LUCENE_30,
                                                    indexReader.GetFieldNames(
                                                        IndexReader.FieldOption.INDEXED_NO_TERMVECTOR).ToArray(),
                                                    analyzer);
        }

        //Add a fuzzy search using a tilde on each word in the phrase then 'AND' them together.
        var booleanQueries = new List<BooleanQuery>();
        foreach (var phrase in phrases)
        {
            var terms = phrase.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
            var booleanQuery = new BooleanQuery();
            foreach (var term in terms)
            {
                booleanQuery.Add(queryParser.Parse(term.Replace("~", "") + "~"), Occur.MUST);
                    //'AND' the words in the phrase together.
            }
            booleanQueries.Add(booleanQuery);
        }

        //combine our boolean queries with 'OR' i.e. (word1 and word2 and word3) OR (word4 and word5) OR (word 6)
        var combined = new BooleanQuery();
        foreach (var query in booleanQueries)
        {
            combined.Add(query, Occur.SHOULD);
        }


        var maxHits = 100; //TODO - configurable
        var collector = TopScoreDocCollector.Create(maxHits, true);
        searcher.Search(combined, collector);
        var hits = collector.TopDocs().ScoreDocs;


        foreach (var t in hits)
        {
            var hitDoc = searcher.Doc(t.Doc);
            var indexDoc = new DocumentWrapper();
            foreach (var field in hitDoc.GetFields())
            {
                if (field.Name == "Score")
                {
                    indexDoc.Contents.Add(field.Name, t.Score);
                }
                else
                {
                    indexDoc.Contents.Add(field.Name, hitDoc.Get(field.Name));
                }
            }
            matchedDocuments.Add(indexDoc);
        }
    }
    catch
    {
        //TODO - Logging?
    }

    return matchedDocuments;
}
4

0 に答える 0