Lucene高级查询

文本搜索

QueryParser可以指定默认域,queryParser.parse中又可以用域名:关键词来覆盖它。如果parse中没有指定搜索域就使用默认域。

@Test
public void testIndexSearch() throws Exception {
    // 1. 创建Query搜索对象
    // 创建分词器
    Analyzer analyzer = new IKAnalyzer();
    // 创建搜索解析器,第一个参数:默认Field域,第二个参数:分词器
    QueryParser queryParser = new QueryParser("brandName", analyzer);
    // 创建搜索对象
    Query query = queryParser.parse("name:华为手机");
    // 2. 创建Directory流对象,声明索引库位置
    Directory directory = FSDirectory.open(Paths.get("E:\\dir"));
    // 3. 创建索引读取对象IndexReader
    IndexReader reader = DirectoryReader.open(directory);
    // 4. 创建索引搜索对象
    IndexSearcher searcher = new IndexSearcher(reader);
    // 5. 使用索引搜索对象,执行搜索,返回结果集TopDocs
    // 第一个参数:搜索对象,第二个参数:返回的数据条数,指定查询结果最顶部的n条数据返回
    TopDocs topDocs = searcher.search(query, 50);
    System.out.println("查询到的数据总条数是:" + topDocs.totalHits);
    // 获取查询结果集
    ScoreDoc[] docs = topDocs.scoreDocs;
    // 6. 解析结果集
    for (ScoreDoc scoreDoc : docs) {
        // 获取文档
        int docID = scoreDoc.doc;
        Document doc = searcher.doc(docID);
        System.out.println("=============================");
        System.out.println("docID:" + 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("brandName:" + doc.get("brandName"));
        System.out.println("image:" + doc.get("image"));
    }
    // 7. 释放资源
    reader.close();
}

queryParser.parse更多用法:

使用AND求并集,使用OR求交集,注意必须大写

queryParser.parse("华为 AND 手机")
queryParser.parse("华为 OR 手机")

数值范围查询

例如: 查询价格大于等于100, 小于等于1000的商品

@Test
public void testRangeQuery() throws Exception {
    // 1. 创建Query搜索对象
    Query query = FloatPoint.newRangeQuery("price", 100, 1000);
    // 2. 创建Directory流对象,声明索引库位置
    Directory directory = FSDirectory.open(Paths.get("E:\\dir"));
    // 3. 创建索引读取对象IndexReader
    IndexReader reader = DirectoryReader.open(directory);
    // 4. 创建索引搜索对象
    IndexSearcher searcher = new IndexSearcher(reader);
    // 5. 使用索引搜索对象,执行搜索,返回结果集TopDocs
    // 第一个参数:搜索对象,第二个参数:返回的数据条数,指定查询结果最顶部的n条数据返回
    TopDocs topDocs = searcher.search(query, 10);
    System.out.println("查询到的数据总条数是:" + topDocs.totalHits);
    // 获取查询结果集
    ScoreDoc[] docs = topDocs.scoreDocs;
    // 6. 解析结果集
    for (ScoreDoc scoreDoc : docs) {
        // 获取文档
        int docID = scoreDoc.doc;
        Document doc = searcher.doc(docID);
        System.out.println("=============================");
        System.out.println("docID:" + 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("brandName:" + doc.get("brandName"));
        System.out.println("image:" + doc.get("image"));
    }
    // 7. 释放资源
    reader.close();
}

组合查询

组合查询可以组合多个查询对象,即多个条件,使用BooleanQuery.Builder构造。

每联系一个Query对象,可以指定:

  • BooleanClause.Occur.MUST 必须 相当于and, 并且
  • BooleanClause.Occur.MUST_NOT 不必须 相当于not, 非
  • BooleanClause.Occur.SHOULD 应该 相当于or, 或者

注意: 如果逻辑条件中, 只有MUST_NOT, 或者多个逻辑条件都是MUST_NOT, 无效, 查询不出任何数据。

@Test
public void testBooleanSearch() throws Exception {
    // 创建分词器
    Analyzer analyzer = new IKAnalyzer();
    // 创建数值范围搜索对象
    Query query1 = FloatPoint.newRangeQuery("price", 100, 1000);
    QueryParser queryParser = new QueryParser("name", analyzer);
    // 创建搜索对象
    Query query2 = queryParser.parse("华为手机");
    // 创建组合搜索对象
    BooleanQuery.Builder builder = new BooleanQuery.Builder();
    builder.add(new BooleanClause(query1, BooleanClause.Occur.MUST));
    builder.add(new BooleanClause(query2, BooleanClause.Occur.MUST_NOT));
    // 2. 创建Directory流对象,声明索引库位置
    Directory directory = FSDirectory.open(Paths.get("E:\\dir"));
    // 3. 创建索引读取对象IndexReader
    IndexReader reader = DirectoryReader.open(directory);
    // 4. 创建索引搜索对象
    IndexSearcher searcher = new IndexSearcher(reader);
    // 5. 使用索引搜索对象,执行搜索,返回结果集TopDocs
    // 第一个参数:搜索对象,第二个参数:返回的数据条数,指定查询结果最顶部的n条数据返回
    TopDocs topDocs = searcher.search(builder.build(), 10);
    System.out.println("查询到的数据总条数是:" + topDocs.totalHits);
    // 获取查询结果集
    ScoreDoc[] docs = topDocs.scoreDocs;
    // 6. 解析结果集
    for (ScoreDoc scoreDoc : docs) {
        // 获取文档
        int docID = scoreDoc.doc;
        Document doc = searcher.doc(docID);
        System.out.println("=============================");
        System.out.println("docID:" + 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("brandName:" + doc.get("brandName"));
        System.out.println("image:" + doc.get("image"));
    }
    // 7. 释放资源
    reader.close();
}

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/lucene%e9%ab%98%e7%ba%a7%e6%9f%a5%e8%af%a2/