Нет поисков при поиске "mvc2" с lucene.net - PullRequest
3 голосов
/ 12 ноября 2011

Я занимаюсь индексированием и поиском с помощью lucene.net, единственная проблема, с которой я сталкиваюсь в своем коде, заключается в том, что он не находит никаких совпадений при поиске «mvc2» (похоже, он работает со всеми другими словами, которые я ищу),Я пробовал другой анализатор (см. Комментарии к анализатору) и более старый код lucene, вот мой индекс и код поиска, я был бы очень признателен, если бы кто-то мог показать мне, где я ошибаюсь, Спасибо.

////Indexing code
public void DoIndexing(string CvContent)
    {
        //state the file location of the index
        const string indexFileLocation = @"C:\RecruitmentIndexer\IndexedCVs";

        //if directory does not exist, create it, and create new index for it.
        //if directory does exist, do not create directory, do not create new      //index(add field to previous index).
        bool creatNewDirectory;   //to pass into lucene GetDirectory
        bool createNewIndex;      //to pass into lucene indexWriter
        if (!Directory.Exists(indexFileLocation))
        {
            creatNewDirectory = true;
            createNewIndex = true;
        }
        else
        {
            creatNewDirectory = false;
            createNewIndex = false;
        }


        Lucene.Net.Store.Directory dir =
            Lucene.Net.Store.FSDirectory.GetDirectory(indexFileLocation, creatNewDirectory);//creates if true

        //create an analyzer to process the text
        Lucene.Net.Analysis.Analyzer analyzer = new
        Lucene.Net.Analysis.SimpleAnalyzer();              //this analyzer gets all //hits exept mvc2 
        //Lucene.Net.Analysis.Standard.StandardAnalyzer(); //this leaves out sql once //and mvc2 once

        //create the index writer with the directory and analyzer defined.
        Lucene.Net.Index.IndexWriter indexWriter = new
        Lucene.Net.Index.IndexWriter(dir, analyzer,
            /*true to create a new index*/ createNewIndex);

        //create a document, add in a single field
        Lucene.Net.Documents.Document doc = new
        Lucene.Net.Documents.Document();



        Lucene.Net.Documents.Field fldContent =
          new Lucene.Net.Documents.Field("content",
          CvContent,//"This is some text to search by indexing",
          Lucene.Net.Documents.Field.Store.YES,
        Lucene.Net.Documents.Field.Index.ANALYZED,
        Lucene.Net.Documents.Field.TermVector.YES);

        doc.Add(fldContent);

        //write the document to the index
        indexWriter.AddDocument(doc);

        //optimize and close the writer
        indexWriter.Optimize();
        indexWriter.Close();

    }
////search code
private void button2_Click(object sender, EventArgs e)
    {

        string SearchString = textBox1.Text;

        ///after creating an index, search
        //state the file location of the index
        const string indexFileLocation = @"C:\RecruitmentIndexer\IndexedCVs";

        Lucene.Net.Store.Directory dir =
        Lucene.Net.Store.FSDirectory.GetDirectory(indexFileLocation, false);

        //create an index searcher that will perform the search
        Lucene.Net.Search.IndexSearcher searcher = new
        Lucene.Net.Search.IndexSearcher(dir);

        SearchString = SearchString.Trim();
        SearchString = QueryParser.Escape(SearchString);


        //build a query object
        Lucene.Net.Index.Term searchTerm =
          new Lucene.Net.Index.Term("content", SearchString);
        Lucene.Net.Search.Query query = new Lucene.Net.Search.TermQuery(searchTerm);

        //execute the query
        Lucene.Net.Search.Hits hits = searcher.Search(query);

        label1.Text = hits.Length().ToString();

        //iterate over the results.
        for (int i = 0; i < hits.Length(); i++)
        {
           Lucene.Net.Documents.Document docMatch = hits.Doc(i);

            MessageBox.Show(docMatch.Get("content"));

        }

    }

1 Ответ

3 голосов
/ 14 ноября 2011

Я считаю, что StandardAnalyzer фактически удаляет «2» из «mvc2», оставляя индексированное слово равным «mvc».Я не уверен насчет SimpleAnalyzer, хотя.Вы можете попробовать использовать WhitespaceAnalyzer, который, я считаю, не удаляет числа.

Вы также должны обрабатывать вводимые данные таким же образом, как при индексировании.TermQuery - это «идентичное» совпадение, что означает, что если вы попытаетесь найти «mvc2», где фактические строки в вашем индексе всегда говорят «mvc», то совпадения не будет.

Я не нашел способа фактически использовать анализатор, если я не использую QueryParser, и даже тогда у меня всегда были странные результаты.

Вы можете попробовать это, чтобы «токенизировать» строку поиска втак же, как вы индексируете свой документ и выполняете логический И поиск по всем терминам:

    // We use a boolean query to combine all prefix queries
    var analyzer = new SimpleAnalyzer();
    var query = new BooleanQuery();

    using ( var reader = new StringReader( queryTerms ) )
    {
        // This is what we need to do in order to get the terms one by one, kind of messy but seemed to be the only way
        var tokenStream = analyzer.TokenStream( "why_do_I_need_this", reader );
        var termAttribute = tokenStream.GetAttribute( typeof( TermAttribute ) ) as TermAttribute;

        // This will return false when all tokens has been processed.
        while ( tokenStream.IncrementToken() )
        {
            var token = termAttribute.Term();
            query.Add( new PrefixQuery( new Term( KEYWORDS_FIELD_NAME, token ) ), BooleanClause.Occur.MUST );
        }

        // I don't know if this is necessary, but can't hurt
        tokenStream.Close();
    }

Вы можете заменить PrefixQuery на TermQuery, если вы хотите только полные совпадения (PrefixQuery будет соответствовать любому, начинающемуся с "* ")

...