2013-03-31 85 views
3

我在Lucene中编写了一个索引搜索器,它将搜索索引数据库中的多个字段。Lucene中的多字段查询处理

其实它需要查询为两个字符串,一个是title,另一个是cityname

现在索引数据库有三个字段:title, address and city

仅当标题匹配和城市名称匹配时才会发生点击。为此目的,我写了使用MultiFieldQuerySearcher与后的帮助下面的搜索代码:

public void searchdb(String myQuery, String myCity) throws Exception 
{ 
    System.out.println("Searching in the database ..."); 
    String[] fields={"title","address","city"}; 
    MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_CURRENT, fields, new StandardAnalyzer(Version.LUCENE_CURRENT)); 
    parser.setDefaultOperator(QueryParser.Operator.AND); 
    if(!myQuery.toLowerCase().contains(myCity.toLowerCase())) 
    { 
     myQuery="title:"+myQuery+" "+"address:"+myQuery+" "+myCity+" "+"city:"+myCity; 
    } 
    Query query=parser.parse(myQuery); 
    if (query instanceof BooleanQuery) 
    { 
     BooleanClause.Occur[] flags ={BooleanClause.Occur.MUST,BooleanClause.Occur.SHOULD,BooleanClause.Occur.MUST}; 
     BooleanQuery booleanQuery = (BooleanQuery) query; 
     BooleanClause[] clauses = booleanQuery.getClauses(); 
     System.out.println("Query="+booleanQuery.toString()+" and Number of clauses="+clauses.length); 
     for (int i = 0; i < clauses.length; i++) 
     { 
      clauses[i].setOccur(flags[i]); 
     } 
     Directory dir=FSDirectory.open(new File("demoIndex")); 
     IndexSearcher searcher = new IndexSearcher(dir, true); 
     TopDocs hits = searcher.search(booleanQuery, 20); 
     searcher.close(); 
     dir.close(); 
     System.out.println("Number of hits="+hits.totalHits); 
    } 
} 

但运行不正常。

例如,如果查询是“必胜客”而城市是“孟买”,我只希望在数据库的标题字段和孟买仅在数据库的城市字段中搜索“必胜客”。

但它是寻找“必胜客”也可在数据库作为语句booleanQuery.toString的输出城市场()即将为“+标题:比萨+(标题:小屋城市:小屋) + city:mumbai“。

作为for循环的结果,它给出索引outOfBound错误。

我是Lucene的新手。所以我正在寻求帮助来解决这个问题。

+0

请问你能分享一下你的代码吗? – jbakirov

回答

7

仅当我们想在多个字段中搜索相同关键字时,我们才使用MultiFieldQueryParser。

要处理您的用例,您已经分别引用city-keyword和title-keyword更简单。尝试使用以下代码。

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); 
// city query 
QueryParser cityQP = new QueryParser(Version.LUCENE_CURRENT, "city", analyzer); 
Query cityQuery = cityQP.parse(myCity); 

// title query 
QueryParser titleQP = new QueryParser(Version.LUCENE_CURRENT, "title", analyzer); 
Query titleQuery = titleQP.parse(myQuery); 

// final query 
BooleanQuery finalQuery = new BooleanQuery(); 
finalQuery.add(cityQuery, Occur.MUST); // MUST implies that the keyword must occur. 
finalQuery.add(titleQuery, Occur.MUST); // Using all "MUST" occurs is equivalent to "AND" operator. 
+0

谢谢,先生:) – Joy

+0

但先生有一个问题。在我的索引中,有一个条目的标题是“必胜客”,城市是“孟买”。当我查询标题为“比萨”和城市“MUmbai”的索引时,命中数量为0.但根据我的理解,这应该是一个,因为这两个术语都出现在其相应的字段中。你能解释一下吗? – Joy

+0

1)确保在索引和查询时使用相同的分析器.--- 2)请将最终查询打印到输出并粘贴到此处.--- 3)使用Luke检查您的索引。它使用简单。它是一个用于探索和检查Lucene索引的GUI工具。请使用Luke检查索引是否包含您所期望的内容.---顺便说一句,请不要再使用“先生”。:) – phani