Lucene中的多字段查询处理

Joy*_*Joy 6 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但它运行不正常.

例如,如果查询是"必胜客"而城市是"孟买",我希望仅在数据库的标题字段中搜索"必胜客",并且仅在数据库的城市字段中搜索孟买.

但它正在数据库的城市领域中发现"Hut",因为语句booleanQuery.toString()的输出将作为" + title:pizza +(title:hut city:hut)+ city:mumbai ".

因此在for循环中它给出了索引outOfBound错误.

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

pha*_*ani 13

我们只在想要在多个字段中搜索相同的关键字时才使用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.
Run Code Online (Sandbox Code Playgroud)