• 8.Lucene多字段搜索


    一、匹配多字段搜索

    在有些情况下,我们需要把输入的关键字在多个字段中进行匹配。

    例如:我们需要在“title”和“content”字段中搜索“组件刷新”这个关键字。

    // 多字段查询,同时在多个字段中进行查询,查询的关键字会进行分词
    String[] fields = {"title", "content"};
    MultiFieldQueryParser multiFieldQuery = new MultiFieldQueryParser(fields, new IKAnalyzer());
    Query query = multiFieldQuery.parse("组件刷新");
    

    组装好查询对象Query后,我们只要把query传给IndexSearcher进行搜索即可。

    // 创建一个索引查询对象
    DirectoryReader reader = DirectoryReader.open(fsd);
    IndexSearcher searcher = new IndexSearcher(reader);
    // 搜索
    TopDocs docs = searcher.search(query, 10);
    

    附录:完整代码

    @Test
    public void multiTermQuery() throws ParseException {
        // lucene索引目录位置
        String indexDir = "E:\develop\demo\lucene-learn\lucene-index";
        File luceneIndexDirectory = new File(indexDir);
        // 打开索引目录
        try (FSDirectory fsd = FSDirectory.open(luceneIndexDirectory.toPath())) {
            // 创建一个索引查询对象
            DirectoryReader reader = DirectoryReader.open(fsd);
            IndexSearcher searcher = new IndexSearcher(reader);
    
            // 多字段查询,同时在多个字段中进行查询,查询的关键字会进行分词
            String[] fields = {"title", "content"};
            MultiFieldQueryParser multiFieldQuery = new MultiFieldQueryParser(fields, new IKAnalyzer());
            Query query = multiFieldQuery.parse("组件刷新");
    
            // 搜索
            TopDocs docs = searcher.search(query, 10);
    
            // 打印
            for (ScoreDoc doc : docs.scoreDocs) {
                Document document = searcher.doc(doc.doc);
                System.out.println(document);
            }
    
            // 关闭查询Reader
            reader.close();
        } catch (IOException e) {
            System.err.println("打开索引目录失败");
            e.printStackTrace();
        }
    }
    

    二、多条件筛选式搜索

    筛选式搜索,就像淘宝一样,在进行搜索的时候选择几个条件。

    例如:在搜索手机时,我们指定品牌为“华为”,然后搜索 ”5G手机“,这种就是多条件筛选式搜索。

    搜索的条件有不同可以制定规则进行布尔运算:
    MUST 与
    MUST_NOT 非
    SHOULD 或
    FILTER 过滤

    我们可以通过2种方式实现:

    1. 组合查询

    定义多个查询条件,然后组合起来,使用BooleanQuery进行布尔运行。

    // 查询 title 包含 刷新
    QueryParser titleQueryParser = new QueryParser("title", new IKAnalyzer());
    Query titleQuery = titleQueryParser.parse("刷新");
    // 查询 content 包含 缓存
    QueryParser contentQueryParser = new QueryParser("content", new IKAnalyzer());
    Query contentQuery = contentQueryParser.parse("缓存");
    // 布尔运算:
    // MUST + MUST = 求2个都有的部分
    Query query = new BooleanQuery.Builder()
        .add(titleQuery, BooleanClause.Occur.MUST)
        .add(contentQuery, BooleanClause.Occur.MUST)
        .build();
    

    2. 多字段查询

    多字段查询也可以支持布尔运算。

    // 查询字段
    String[] fields = {"title", "content"};
    // 查询关键字
    String[] stringQuery = {"刷新", "缓存"};
    // title=刷新 and content=缓存
    BooleanClause.Occur[] flags = {BooleanClause.Occur.MUST, BooleanClause.Occur.MUST};
    Query query = MultiFieldQueryParser.parse(stringQuery, fields, flags, new IKAnalyzer());
    

    附录:完整代码

    @Test
    public void screeningQuery() throws ParseException {
        // lucene索引目录位置
        String indexDir = "E:\develop\demo\lucene-learn\lucene-index";
        File luceneIndexDirectory = new File(indexDir);
        // 打开索引目录
        try (FSDirectory fsd = FSDirectory.open(luceneIndexDirectory.toPath())) {
            // 创建一个索引查询对象
            DirectoryReader reader = DirectoryReader.open(fsd);
            IndexSearcher searcher = new IndexSearcher(reader);
    
            // 筛选式搜索,类似:title=xxx and content=xxx
            // 布尔查询规则,表示查询的结果要如何进行布尔运算
            // 1.MUST       与
            // 2.MUST_NOT   不
            // 3.SHOULD     或
            // 4.FILTER     非
    
            /*
             // 方式一、布尔组合查询
             QueryParser titleQueryParser = new QueryParser("title", new IKAnalyzer());
             Query titleQuery = titleQueryParser.parse("刷新");
             QueryParser contentQueryParser = new QueryParser("content", new IKAnalyzer());
             Query contentQuery = contentQueryParser.parse("缓存");
             // 布尔运算
             Query query = new BooleanQuery.Builder()
                   .add(titleQuery, BooleanClause.Occur.MUST)
                   .add(contentQuery, BooleanClause.Occur.MUST)
                   .build();
             */
    
            // 方式二、多字段查询
            // 查询字段
            String[] fields = {"title", "content"};
            // 查询关键字
            String[] stringQuery = {"刷新", "缓存"};
            // title=刷新 and content=缓存
            BooleanClause.Occur[] flags = {BooleanClause.Occur.MUST, BooleanClause.Occur.MUST};
            Query query = MultiFieldQueryParser.parse(stringQuery, fields, flags, new IKAnalyzer());
    
            // 搜索
            TopDocs docs = searcher.search(query, 10);
    
            // 打印
            for (ScoreDoc doc : docs.scoreDocs) {
                Document document = searcher.doc(doc.doc);
                System.out.println(document);
            }
    
            // 关闭查询Reader
            reader.close();
        } catch (IOException e) {
            System.err.println("打开索引目录失败");
            e.printStackTrace();
        }
    }
    
  • 相关阅读:
    提高.NET编程水平的50个要点(转载)
    动态生成Menu
    C#实现二叉树外带中序遍历(转载)
    我的XML学习笔记<续>
    泛型的排序问题
    我的XML学习笔记
    动态存储过程分页
    排序算法汇总(转载收藏)
    中兴u880e刷机root教程(含刷第三方recover)
    如何清理ipod touch iPhone ipad的“其他”文件
  • 原文地址:https://www.cnblogs.com/lixingwu/p/13870605.html
Copyright © 2020-2023  润新知