1.1 常用的Query子类搜索
1.1.1 TermQuery
特点:查询的关键词不会再做分词处理,作为整体来搜索。代码如下:
/** * Query子类查询之 TermQuery * * 特点:不会再对查询的关键词做分词处理。 * * 需要:查询书名与java教程相关书。 */ @Test public void queryByTermQuery(){ //1、获取一个查询对象 Query query = new TermQuery(new Term("name", "编程思想")); doSearch(query);
} private void doSearch(Query query) { try {
//2、创建一个查询的执行对象 //指定索引库的目录 Directory d = FSDirectory.open(new File("F:\\lucene\\0719")); //创建流对象 IndexReader reader = DirectoryReader.open(d); //创建搜索执行对象 IndexSearcher searcher = new IndexSearcher(reader);
//3、执行搜索 TopDocs result = searcher.search(query, 10);
//4、提出结果集,获取图书的信息 int totalHits = result.totalHits; System.out.println("共查询到"+totalHits+"条满足条件的数据!"); System.out.println("-----------------------------------------"); //提取图书信息。 //score即相关度。即搜索的关键词和 图书名称的相关度,用来做排序处理 ScoreDoc[] scoreDocs = result.scoreDocs;
for (ScoreDoc scoreDoc : scoreDocs) { /** * scoreDoc.doc的返回值,是文档的id, 即 将文档写入索引库的时候,lucene自动给这份文档做的一个编号。 * * 获取到这个文档id之后,即可以根据这个id,找到这份文档。 */ int docId = scoreDoc.doc; System.out.println("文档在索引库中的编号:"+docId);
//从文档中提取图书的信息 Document doc = searcher.doc(docId); System.out.println("图书id:"+doc.get("id")); System.out.println("图书name:"+doc.get("name")); System.out.println("图书price:"+doc.get("price")); System.out.println("图书pic:"+doc.get("pic")); System.out.println("图书description:"+doc.get("description")); System.out.println(); System.out.println("------------------------------------");
}
//关闭连接,释放资源 if(null!=reader){ reader.close(); } } catch (Exception e) { e.printStackTrace(); } } |
1.1.2 NumericRangeQuery
指定数字范围查询.(创建field类型时,注意与之对应)
/** * Query子类查询 之 NumricRangeQuery * 需求:查询所有价格在[60,80)之间的书 * @param query */ @Test public void queryByNumricRangeQuery(){ /** * 第一个参数:要搜索的域 * 第二个参数:最小值 * 第三个参数:最大值 * 第四个参数:是否包含最小值 * 第五个参数:是否包含最大值 */ Query query = NumericRangeQuery.newFloatRange("price", 60.0f, 80.0f, true, false);
doSearch(query); } |
1.1.3 BooleanQuery
BooleanQuery,布尔查询,实现组合条件查询。
/** * Query子类查询 之 BooelanQuery查询 组合条件查询 * * 需求:查询书名包含java,并且价格区间在[60,80)之间的书。 */ @Test public void queryBooleanQuery(){ //1、要使用BooelanQuery查询,首先要把单个创建出来,然后再通过BooelanQuery组合 Query price = NumericRangeQuery.newFloatRange("price", 60.0f, 80.0f, true, false); Query name = new TermQuery(new Term("name", "java"));
//2、创建BooleanQuery实例对象 BooleanQuery query = new BooleanQuery(); query.add(name, Occur.MUST_NOT); query.add(price, Occur.MUST); /** * MSUT 表示必须满足 对应的是 + * MSUT_NOT 必须不满足 应对的是 - * SHOULD 可以满足也可以不满足 没有符号 * * SHOULD 与MUST、MUST_NOT组合的时候,SHOULD就没有意义了。 */
doSearch(query); } |
1.2 通过QueryParser搜索
1.2.1 特点
对搜索的关键词,做分词处理。
1.2.2 语法
1.2.2.1 基础语法
域名:关键字 实例:name:java |
1.2.2.2 组合条件语法
条件1 AND 条件2 条件1 OR 条件2 条件1 NOT 条件2 |
1.2.3 QueryParser
1.2.3.1 代码实现
/** * 查询解析器查询 之 QueryParser查询 */ @Test public void queryByQueryParser(){ try {
//1、加载分词器 Analyzer analyzer = new StandardAnalyzer();
/** * 2、创建查询解析器实例对象 * 第一个参数:默认搜索的域。 * 如果在搜索的时候,没有特别指定搜索的域,则按照默认的域进行搜索 * 如何在搜索的时候指定搜索域呢? * 答:格式 域名:关键词 即 name:java教程 * * 第二个参数:分词器 ,对关键词做分词处理 */ QueryParser parser = new QueryParser("description", analyzer);
Query query = parser.parse("name:java教程");
doSearch(query);
} catch (Exception e) { e.printStackTrace(); } } |
1.2.4 MultiFieldQueryParser
通过MulitFieldQueryParse对多个域查询。
/** * 查询解析器查询 之 MultiFieldQueryParser查询 * * 特点:同时指定多个搜索域,并且对关键做分词处理 */ @Test public void queryByMultiFieldQueryParser(){ try {
//1、定义多个搜索的 name、description String[] fields = {"name","description"}; //2、加载分词器 Analyzer analyzer = new StandardAnalyzer();
//3、创建 MultiFieldQueryParser实例对象 MultiFieldQueryParser mParser = new MultiFieldQueryParser(fields, analyzer);
Query query = mParser.parse("lucene教程");
doSearch(query); } catch (Exception e) { e.printStackTrace(); } } |