3.3.5 布尔查询
可以使用BooleanQuery组合多个查询条件。合取查询使用BooleanClause.Occur.MUST连接多个查询词。
Term t1 = new Term(FIELD, "lucene"); TermQuery q1 = new TermQuery(t1); Term t2 = new Term(FIELD, "doug"); TermQuery q2 = new TermQuery(t2); //合取查询 BooleanQuery query = new BooleanQuery(); query.add(q1, BooleanClause.Occur.MUST); //必须包含这个条件 query.add(q2, BooleanClause.Occur.MUST);
选择出包含任何一个查询词的文档叫作析取(Disjunction)。用真值表描述析取如下。
析取查询使用BooleanClause.Occur.SHOULD连接多个查询词。
//析取查询 BooleanQuery q = new BooleanQuery(); q.Add(q1, BooleanClause.Occur.SHOULD); //可以只包含这个条件 q.Add(q2, BooleanClause.Occur.SHOULD);
例如去餐馆点菜,有人不喜欢吃辣的东西,所以他找出所有不辣的菜,这叫作否定(Negation)。用真值表描述否定如下。
BooleanClause.Occur.MUST_NOT表示不能包括符合这个条件的文档。例如找出不包含“辣”的所有文档。
Term t1 = new Term("body", "辣"); TermQuery q1 = new TermQuery(t1); BooleanQuery mbq = new BooleanQuery(); MatchAllDocsQuery alldocs = new MatchAllDocsQuery(); //匹配所有文档 mbq.Add(q1, BooleanClause.Occur.MUST_NOT); //不包括满足q1条件的文档 mbq.Add(alldocs, BooleanClause.Occur.MUST);
打麻将三缺一不行,但是如果同时查询多个词,最好只差一个查询词的文档也能匹配。
对于长句搜索,则提取其中的主要查询词,只要大部分词在文档中出现就可以了。例如搜索联系方式列:
● "Stanford University School of Medicine, Palo Alto, CA USA",
● "Institute of Neurobiology, School of Medicine, Stanford University, Palo Alto, CA",
● "School of Medicine, Harvard University, Boston MA",
● "Brigham & Women's, Harvard University School of Medicine, Boston, MA"
● "Harvard University, Cambridge MA"
搜索联系方式使用如下的长查询词:
"School of Medicine, Stanford University, Palo Alto, CA"
需要找到所有和Stanford相关的文档。
PhraseQuery要求短语中所有的词都存在才能匹配。这里需要一个更加宽松的PhraseQuery版本,要求它对词出现的顺序敏感,但是允许缺少个别词,缺少词的文档分值低,但是仍然能匹配。BooleanQuery.setMinimumNumberShouldMatch(int)方法可以定义需要匹配的条件的最小数量。
例如,BooleanQuery中有2项,调用BooleanQuery.setMinimumNumberShouldMatch(1)方法可以匹配其中任意的1项或者更多。
Term t1 = new Term(FIELD, "鸡"); TermQuery q1 = new TermQuery(t1); Term t2 = new Term(FIELD, "鸭"); TermQuery q2 = new TermQuery(t2); BooleanQuery mbq = new BooleanQuery(); mbq.add(q1 , BooleanClause.Occur.SHOULD); mbq.add(q2 , BooleanClause.Occur.SHOULD); mbq.setMinimumNumberShouldMatch(1);