简体   繁体   中英

Incremental search using Lucene

I want to do incremental search using lucene.I have got white space inbetween words. Say "India today" .My search query returns

  • India today
  • Today india time
  • Today time India

I want the search to result such as "India today%" in sql. But this is not happening. I tried using phrase query but that works for exact search.My stored data is NOT_ANALYZED so that i can search with space.

KeywordAnalyzer analyzer = new KeywordAnalyzer (); 

PhraseQuery pq = new  PhraseQuery();
pq.add(new Term("name", "MR DANIEL KELLEHER")); 


int hitsPerPage = 1000;
IndexReader reader = IndexReader.open(index);
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
searcher.search(pq, collector);

I am not able to get like query which has space inbetween.I have referred many articles on net and stackoverflow as well but not getting solution.

package org.lucenesample;

import org.apache.lucene.search.Query;

import org.apache.lucene.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.analysis.standard.std31.*;
import org.apache.lucene.analysis.tokenattributes.*;
import org.apache.lucene.collation.*;
import org.apache.lucene.document.*;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.*;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.messages.*;
import org.apache.lucene.queryParser.*;
import org.apache.lucene.search.*;
import org.apache.lucene.search.function.*;
import org.apache.lucene.search.payloads.*;
import org.apache.lucene.search.spans.*;
import org.apache.lucene.store.*;
import org.apache.lucene.util.*;
import org.apache.lucene.util.fst.*;
import org.apache.lucene.util.packed.*;

import java.io.File;
import java.sql.*;
import java.util.HashMap;

public class ExactPhrasesearchUsingStandardAnalyser {

    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        Directory directory = new RAMDirectory();
        StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
        MaxFieldLength mlf = MaxFieldLength.UNLIMITED;
        IndexWriter writer = new IndexWriter(directory, analyzer, true, mlf);
        writer.addDocument(createDocument1("1", "foo bar baz blue"));
        writer.addDocument(createDocument1("2", "red green blue"));
        writer.addDocument(createDocument1("3", "test panda foo & bar testt"));
        writer.addDocument(createDocument1("4", " bar test test foo in panda  red blue "));
        writer.addDocument(createDocument1("4", "test"));
        writer.close();

    IndexSearcher searcher = new IndexSearcher(directory);
    PhraseQuery query = new PhraseQuery();


    QueryParser qp2 = new QueryParser(Version.LUCENE_35, "contents", analyzer);
    //qp.setDefaultOperator(QueryParser.Operator.AND);
    Query queryx2 =qp2.parse("test foo in panda re*");//contains query
    Query queryx23 =qp2.parse("+red +green +blu*"  );//exact phrase match query.Make last word as followed by star
    Query queryx234 =qp2.parse("(+red +green +blu*)& (\"red* green\") "  );





     /*String term = "new york";
        // id and location are the fields in which i want to search the "term"
        MultiFieldQueryParser queryParser = new MultiFieldQueryParser(
                                           Version.LUCENE_35,
                                           { "contents"},
                                           new KeywordAnalyzer());
        Query query = queryParser.parse(term);
        System.out.println(query.toString());*/

    QueryParser qp = new QueryParser(Version.LUCENE_35, "contents", analyzer);
    //qp.setDefaultOperator(QueryParser.Operator.AND);

    Query queryx =qp.parse("\"air quality\"~10");
    System.out.println("******************Searching Code starts******************");
    TopDocs topDocs = searcher.search(queryx2, 10);
    for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
        Document doc = searcher.doc(scoreDoc.doc);
        System.out.println(doc+"testtttttttt");
    }

}



   private static Document createDocument1(String id, String content) {
        Document doc = new Document();
        doc.add(new Field("id", id, Store.YES, Index.NOT_ANALYZED));
        doc.add(new Field("contents", content, Store.YES, Index.ANALYZED,
                Field.TermVector.WITH_POSITIONS_OFFSETS));
        System.out.println(content);
        return doc;
    }
}

I tried this way.I can search for contains format .But i am not able to get the starts with option so that when user presses "India to" then "India tomorrow" and "india today" results also appear.I am able to get near to it when i do "+india* +to*" But this results "Indians today" as well .I am not able to get search results till user types complete "today" .Basically i want phrase query "\\"india today\\" to work.

For an analyzed field, one way is to use a MultiPhraseQuery with the prefix terms already enumerated:

<MultiPhraseQuery: field:"india (today todays)">

Alternatively a SpanQuery could be used, the advantage being it will handle the term expansion.

<SpanNearQuery: spanNear([field:india, SpanMultiTermQueryWrapper(field:today*)], 0, true)>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM