版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36059561/article/details/83218591
一、前缀搜索
// 前缀查询
public void searchByPrefix(String field, String name, int number) {
IndexSearcher indexSearcher = getIndexSearcher();
try {
Query query = new PrefixQuery(new Term(field, name));
TopDocs topDocs = indexSearcher.search(query, number);
System.out.println("一共查询到:" + topDocs.totalHits);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("id") + " " + document.get("name") + " " + document.get("email"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexSearcher != null) {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、通配符搜索
// 通配符查询
public void searchByWildcard(String field, String name, int number) {
IndexSearcher indexSearcher = getIndexSearcher();
try {
// 在传入的name中可以使用通配符,有?和*两种,?表示匹配一个字符,*表示匹配任意多个字符
Query query = new WildcardQuery(new Term(field, name));
TopDocs topDocs = indexSearcher.search(query, number);
System.out.println("一共查询到:" + topDocs.totalHits);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("id") + " " + document.get("name") + " " + document.get("email"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexSearcher != null) {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
三、布尔查询
可以使用布尔查询来组合查询,使用MUST、SHOULD、MUST_NOT把要筛选的情况构造出来即可。
// 布尔查询
public void searchByBoolean(int number) {
IndexSearcher indexSearcher = getIndexSearcher();
try {
BooleanQuery booleanQuery = new BooleanQuery();
// MUST:必须出现;SHOULD:可以出现也可以不出现;MUST_NOT:不能出现
booleanQuery.add(new TermQuery(new Term("name", "lisi")), BooleanClause.Occur.MUST);
booleanQuery.add(new TermQuery(new Term("content", "content")), BooleanClause.Occur.SHOULD);
booleanQuery.add(new TermQuery(new Term("email", "[email protected]")), BooleanClause.Occur.MUST_NOT);
TopDocs topDocs = indexSearcher.search(booleanQuery, number);
System.out.println("一共查询到:" + topDocs.totalHits);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("id") + " " + document.get("name") + " " + document.get("email"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexSearcher != null) {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
四、短语查询
关于这里的setSlop(),多说两句,slop是移动距离的意思,假如要查询的内容是I like football,首先setSlop(1),再去add对content域查询i和对content域查询football,可以查询出来,如果我将i和football的add顺序颠倒一下,再次查询,会发现没有结果,此时,如果我将setSlop()的参数改为3,再去查询,就会查到刚刚的数据,这是为什么呢?
因为这个slop不是单纯的指单词间距,而是移动距离,对于添加顺序是football i的情况,football右移1位,football和i重叠,右移2位,变成i football,右移3位,变成i * football,此时正好可以匹配上i like football。所以说setSlop()为3反而能查到是这个原因。如果我们setSlop(4)呢?经过查询发现也能查到,也就是说我们set的这个slop是一个最大值,小于等于当前值的也包括在内。
另外,这个查询需要对字符进行移动,对性能有一定的影响,所以要尽量使用。
最后一点,这个查询不支持中文,因为查询中的短语间距分词是以空格作为标志的,所以只能适用于英文查询。
// 短语查询
public void searchByPhrase(int number) {
IndexSearcher indexSearcher = getIndexSearcher();
try {
PhraseQuery phraseQuery = new PhraseQuery();
// 设置短语距离
phraseQuery.setSlop(1);
// 原文是“I like football”,但是这里的I会被转化为小写,所以查询的时候也是使用小写
phraseQuery.add(new Term("content","i"));
phraseQuery.add(new Term("content","football"));
TopDocs topDocs = indexSearcher.search(phraseQuery, number);
System.out.println("一共查询到:" + topDocs.totalHits);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("id") + " " + document.get("name") + " " + document.get("email"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexSearcher != null) {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
五、模糊查询
我们需要查询lisi,但是我们输入的是lixi,发现也可以查询出来,这就是模糊查询,它允许我们错误输入某些字符,但是当我们改为bixi,发现就查不到了,说明模糊查询允许我们输入错误一个字符。我们可以通过构造函数来修改这个相似程度。简单了解下即可,对中文的支持也不好。
// 模糊查询
public void searchByFuzzy(int number) {
IndexSearcher indexSearcher = getIndexSearcher();
try {
// FuzzyQuery(Term term, float minimumSimilarity, int prefixLength, int maxExpansions)
// minimumSimilarity是最小相似度,取值范围为0.0~1.0,包含0.0但不包含1.0,默认值为0.5
// 当这个值越小,通过模糊查找出的文档的匹配程度就越低,文档的数量也就越多;当这个值越大,说明要匹配程度更大,匹配的文档数也就越少
// 当相似度设置为1,那么就退化为TermQuery查询,所以当这个值>=1或<0会抛出IllegalArgumentException异常
// prefixLength是前缀长度,默认为0,表示在进行模糊匹配的时候,要有多少个前缀字母必须完全匹配
Query query = new FuzzyQuery(new Term("name", "lixi"));
TopDocs topDocs = indexSearcher.search(query, number);
System.out.println("一共查询到:" + topDocs.totalHits);
for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
System.out.println(document.get("id") + " " + document.get("name") + " " + document.get("email"));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexSearcher != null) {
try {
indexSearcher.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}