我是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”返回 我的代码中有什么问题?
答案 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)