具有两个指定单词的lucene查询语法

时间:2015-06-18 12:59:59

标签: lucene

我是lucene的初学者。 我在文档中有一个字段名称fstname。 如何在fstname字段中检索同时包含“vamshi”和“sai”字样的文档?

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()
           +")";
}
}

现在我用查询搜索

TopDocs topDocs = new SearchEngine()。performSearch(“fstname:vamshi AND fstname:krishna”,100);

它不会将带有fstname的文件作为“vamshi krishna”返回 我的代码中有什么问题?

2 个答案:

答案 0 :(得分:2)

这是一个简单的布尔AND查询:

  

fstname:vamshi AND fstname:sai

StandardQueryParser会将其转换为查询:

  

+ fstname:vamshi + fstname:sai

编辑:

您的代码中存在一个问题。您正在使用StringFields存储酒店名称。但是StringFields仅被编入索引,但未被标记化。 (see here)这意味着它们不会被分解为单个令牌。如果你添加" vamshi krishna"那么这并没有被标记为" vamshi"和"克里希纳"但只是存储为" vamshi krishna"。

尝试使用常规TextField,它应该有效。

答案 1 :(得分:0)

尝试使用这些:

fstname:vamshi*sai OR fstname:sai*vamshi

正如您所看到的,这是搜索文本模式。这可能会有性能问题。 尝试查看here以获取更多信息。