Lucene中的多字段查询处理

Lucene中的多字段查询处理,lucene,Lucene,我在Lucene中编写了一个索引搜索器,它将搜索索引数据库中的多个字段 实际上,它将查询作为两个字符串,一个是title,另一个是cityname 现在索引数据库有三个字段:标题、地址和城市 只有当标题和城市名称匹配时,才会出现Hit。为此,我在一篇帖子的帮助下,使用multifieldquerysarcher编写了以下搜索程序代码: public void searchdb(String myQuery, String myCity) throws Exception { System

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

实际上,它将查询作为两个字符串,一个是
title
,另一个是
cityname

现在索引数据库有三个字段:
标题、地址和城市

只有当标题和城市名称匹配时,才会出现Hit。为此,我在一篇帖子的帮助下,使用
multifieldquerysarcher
编写了以下搜索程序代码:

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);
    }
}
public void searchdb(字符串myQuery,字符串myCity)引发异常
{
System.out.println(“在数据库中搜索…”);
字符串[]字段={“标题”、“地址”、“城市”};
MultiFieldQueryParser解析器=新的MultiFieldQueryParser(Version.LUCENE_CURRENT,fields,新的StandardAnalyzer(Version.LUCENE_CURRENT));
setDefaultOperator(QueryParser.Operator.AND);
如果(!myQuery.toLowerCase()。包含(myCity.toLowerCase())
{
myQuery=“title:”+myQuery+“+”地址:“+myQuery+”+myCity+”+“city:”+myCity;
}
Query=parser.parse(myQuery);
if(布尔查询的查询实例)
{
BooleanClause.occure[]标志={BooleanClause.occure.MUST,BooleanClause.occure.SHOULD,BooleanClause.occure.MUST};
布尔查询布尔查询=(布尔查询)查询;
BooleanClause[]子句=booleanQuery.getClaires();
System.out.println(“Query=“+booleanQuery.toString()+”和子句数=“+子句.length”);
for(int i=0;i
但它运行不正常

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

但它也在数据库的city字段中找到“Hut”作为booleanQuery语句的输出。toString()的形式是“+title:pizza+(title:Hut-city:Hut)+city:mumbai”

结果,在for循环中,它给出了索引出绑定错误


我是Lucene的新手。因此,我请求帮助解决此问题。

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

为了处理您的用例,更简单的是您已经分别引用了city关键字和title关键字。尝试使用以下代码

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.

但主席先生,有一个问题。在我的索引中有一个条目,标题是“必胜客”,城市是“孟买”。当我查询标题为“Pizza”和城市“MUmbai”的索引时,命中率为0。但根据我的理解,这应该是一个术语,因为这两个术语都存在于它们相应的字段中。你能解释一下吗?1)确保在索引和查询时使用相同的分析器。--2)请将最终查询打印到输出并粘贴到此处。--3)使用Luke检查索引。使用起来非常简单。它是一个GUI工具,用于探索和检查Lucene索引。使用Luke检查索引是否包含您期望的内容。--顺便说一句,请不要再使用“先生”。)最后一个查询是:+城市:孟买+标题:比萨饼。是的,我在索引和查询期间都使用了StandardAnalyzer()。是的,我已经安装了LukeAll。无索引城市名称,即孟买未小写,但在查询中城市名称为小写。也许这就是为什么点击次数变为零。但这怎么可能呢?在这两种情况下,我都使用了相同的分析器。实际上,首先我在索引处做了未分析的城市字段。所以在索引中它不是小写的,甚至在纠正之后,我忘了再次运行索引器。相反,我一次又一次地运行搜索器,所以在Luke中,我看到城市字段不是小写的。这就是不匹配的原因。对不起,我弄错了。你能分享一下你的代码吗?