0
votes

I am beginner to lucene. I have a field name fstname in document. How can I retrieve documents having both the words "vamshi" and "sai" in the fstname field?

public class Indexer 
{
public Indexer() {}
private IndexWriter indexWriter = null;
public IndexWriter getIndexWriter(boolean create) throws IOException 
{
    if (indexWriter == null) 
    {
        File file=new File("D:/index-directory");
        Path dirPath = file.toPath();
        Directory indexDir = FSDirectory.open(file);
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_2,new StandardAnalyzer());
        indexWriter = new IndexWriter(indexDir, config);
    }
    return indexWriter;
   }    
public void closeIndexWriter() throws IOException
{
    if (indexWriter != null) 
    {
        indexWriter.close();
    }
   }   
    public void indexHotel(Hotel hotel) throws IOException 
{
    IndexWriter writer = getIndexWriter(false);
    Document doc = new Document();
    doc.add(new StringField("id", hotel.getId(), Field.Store.YES));
    doc.add(new StringField("fstname", hotel.getFstname(), Field.Store.YES));
    doc.add(new StringField("lastname", hotel.getLastname(), Field.Store.YES));
    doc.add(new LongField("mobileno", hotel.getMobileno(), Field.Store.YES));
    String fullSearchableText = hotel.getId()+" "+hotel.getFstname()+ " " + hotel.getLastname() + " " + hotel.getMobileno();
    doc.add(new TextField("content", fullSearchableText, Field.Store.NO));
    writer.addDocument(doc);
}   
public void rebuildIndexes() throws IOException 
{
      getIndexWriter(true);
      indexWriter.deleteAll();
      Hotel[] hotels = HotelDatabase.getHotels();
      for(Hotel hotel : hotels) 
      {
          indexHotel(hotel);              
      }
      closeIndexWriter();
 }    
}





public class SearchEngine 
{
private IndexSearcher searcher = null;
private QueryParser parser = null;

/** Creates a new instance of SearchEngine */
public SearchEngine() throws IOException 
{
    File file=new File("D:/index-directory");
    Path dirPath = file.toPath();

    searcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(file)));
    parser = new QueryParser("content", new StandardAnalyzer());
}

public TopDocs performSearch(String queryString, int n)
throws IOException, ParseException 
{

    Query query = parser.parse(queryString);        
    return searcher.search(query, n);
}

public Document getDocument(int docId)
throws IOException {
    return searcher.doc(docId);
} 
}





public class HotelDatabase 
{    
private static final Hotel[] HOTELS = {    
    new Hotel("1","vamshi","chinta",9158191135L),
    new Hotel("2","vamshi krishna","chinta",9158191136L),
    new Hotel("3","krishna","chinta",9158191137L),
    new Hotel("4","vamshi","something",9158191138L),
    new Hotel("5","venky","abc",123456789L),
    new Hotel("6","churukoti","def",123456789L),
    new Hotel("7","chinta","vamshi",9158191139L),
    new Hotel("8","chinta","krishna vamshi",9158191139L),
    };

public static Hotel[] getHotels() {
    return HOTELS;
}

public static Hotel getHotel(String id) {
    for(Hotel hotel : HOTELS) {
        if (id.equals(hotel.getId())) {
            return hotel;
        }
    }
    return null;
}
}



public class Hotel 
{

private String fstname;
private String lastname;
private long mobileno;
private String id;
public void setMobileno(long mobileno) {
    this.mobileno = mobileno;
}


public Hotel() 
{
}
public Hotel(String id, 
             String fstname, 
             String lastname, 
             Long mobileno) {
    this.id = id;     
    this.fstname = fstname;     
    this.lastname = lastname;     
    this.mobileno = mobileno;     
}


public String getFstname() {
    return fstname;
}
public void setFstname(String fstname) {
    this.fstname = fstname;
}
public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getLastname() {
    return lastname;
}
public void setLastname(String lastname) {
    this.lastname = lastname;
}
public long getMobileno() {
    return mobileno;
}
public void setMobileno(int mobileno) {
    this.mobileno = mobileno;
}
public String toString() {
    return "Hotel "
           + getId()
           +": "
           + getFstname()
           +" ("
           + getLastname()
           +")";
}
}

now when i search with the query


TopDocs topDocs=new SearchEngine().performSearch("fstname:vamshi AND fstname:krishna", 100);


it is not returning document with fstname as "vamshi krishna" what is the problem in my code??

2

2 Answers

2
votes

This is a simple boolean AND query:

fstname:vamshi AND fstname:sai

The StandardQueryParser will translate this into the query:

+fstname:vamshi +fstname:sai

Edit:

There is one problem in your code. You are using StringFields to store the hotel names. However StringFields are only indexed but not tokenized. (see here) That means that they are not being broken down into the individual tokens. If you add "vamshi krishna" then this is not being tokenized into "vamshi" and "krishna" but just stored as "vamshi krishna".

Try using a regular TextField and it should work.

0
votes

Try using these:

fstname:vamshi*sai OR fstname:sai*vamshi

As you can see this is searching for text pattern. This probably will gonna have performance issues. Try looking here for more information.