• Lucene的查询及高级内容


    Lucene查询

    基本查询:

        @Test
        public void baseQuery() throws Exception {
            //1. 创建查询的核心对象
            FSDirectory d = FSDirectory.open(new File("H:\test"));
            IndexReader reader = DirectoryReader.open(d);
            IndexSearcher indexSearcher = new IndexSearcher(reader);
    
            //2. 执行查询
            QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
            Query query = queryParser.parse("剑来");
            TopDocs topDocs = indexSearcher.search(query, 10);
    
            //3. 获取文档id
            ScoreDoc[] scoreDocs = topDocs.scoreDocs; //获取得分文档集合
            for (ScoreDoc scoreDoc : scoreDocs) {
                int id = scoreDoc.doc;//获取文档id
                float score = scoreDoc.score;// 返回此文档的匹配度
    
                Document doc = indexSearcher.doc(id);
                String docId = doc.get("id");
                String content = doc.get("content");
                System.out.println(docId + "   " + content + "  " + "匹配度:" + score);
            }
        }

    多样化查询:

        //提取一个查询的方法
        public void query(Query query) throws Exception {
    
            //1. 创建 查询的核心对象
            IndexReader reader = DirectoryReader.open(FSDirectory.open(new File("H:\test")));
            IndexSearcher indexSearcher = new IndexSearcher(reader);
    
            //3. 执行查询
            TopDocs topDocs = indexSearcher.search(query, 10);
    
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;//获取得分文档的集合
            for (ScoreDoc scoreDoc : scoreDocs) {
                //获取文档id
                int docId = scoreDoc.doc;
                //获取文档得分
                float score = scoreDoc.score;
                //根据id获取文档
                Document doc = indexSearcher.doc(docId);
                String content = doc.get("content");
                String title = doc.get("title");
                System.out.println("匹配度:" + score + content + "  " + title);
    
            }
        }
    
        // 词条查询
        @Test
        public void termQuery() throws Exception {
            //创建词条对象
            //注意: 词条是不可在分割的, 词条可以是一个字, 也可以是一句话
            //使用场景: 主要是针对的是不可在分割的字段, 例如id
            //由于其不可再分, 可以搜索  全文, 但是不能搜索 全文检索
            TermQuery termQuery = new TermQuery(new Term("content", "全文"));
            query(termQuery);
        }
    
        // 通配符查询
        @Test
        public void wildcardQuery() throws Exception {
    
            //通配符:
            //*:  代表多个字符
            //?: 代表一个占位符
            WildcardQuery wildcardQuery = new WildcardQuery(new Term("content", "?uce*"));
            query(wildcardQuery);
    
        }
    
        //模糊查询
        @Test
        public void fuzzQuery() throws Exception {
            /**
             * 模糊查询:
             *      指的是通过替换, 补位, 移动 能够在二次切换内查询数据即可返回
             *      参数1: term  指定查询的字段和内容
             *      参数2: int n   表示最大编辑的次数  最大2
             *
             */
            FuzzyQuery fuzzyQuery = new FuzzyQuery(new Term("content", "lucene"), 1);
            query(fuzzyQuery);
        }
    
        // 数值范围查询
        @Test
        public void numericRangeQuery() throws Exception {
            /**
             * 获取NumericRangeQuery的方式:
             *      通过提供的静态方法获取:
             *          NumericRangeQuery.newIntRange()
             *          NumericRangeQuery.newFloatRange()
             *          NumericRangeQuery.newDoubleRange()
             *          NumericRangeQuery.newLongRange()
             *
             *
             * 数值范围查询:
             *      参数1: 指定要查询的字段
             *      参数2: 指定要查询的开始值
             *      参数3: 指定要查询的结束值
             *      参数4: 是否包含开始
             *      参数5: 是否包含结束
             */
    
            NumericRangeQuery numericRangeQuery = NumericRangeQuery.newIntRange("id", 2, 4, false, false);
            query(numericRangeQuery);
        }
    
        // 组合查询
        @Test
        public void testBooleanQuery() throws Exception {
    
            Query query1 = NumericRangeQuery.newLongRange("id", 2l, 4l, true, true);
            Query query2 = NumericRangeQuery.newLongRange("id", 0l, 3l, true, true);
    
            // boolean查询本身没有查询条件,它可以组合其他查询
            BooleanQuery query = new BooleanQuery();
            // 交集: Occur.MUST + Occur.MUST
            // 并集:Occur.SHOULD + Occur.SHOULD
            // 非:Occur.MUST_NOT
            query.add(query1, BooleanClause.Occur.SHOULD);
            query.add(query2, BooleanClause.Occur.SHOULD);
    
            query(query);
        }

    Lucene高级内容:

    高亮:

        // 高亮显示
        @Test
        public void testHighlighter() throws Exception {
            // 目录对象
            Directory directory = FSDirectory.open(new File("H:\test"));
            // 创建读取工具
            IndexReader reader = DirectoryReader.open(directory);
            // 创建搜索工具
            IndexSearcher searcher = new IndexSearcher(reader);
    
            QueryParser parser = new QueryParser("title", new IKAnalyzer());
            Query query = parser.parse("谷歌地图");
            
            // 格式化器
            Formatter formatter = new SimpleHTMLFormatter("<em>", "</em>");
            Scorer scorer = new QueryScorer(query);
            // 准备高亮工具
            Highlighter highlighter = new Highlighter(formatter, scorer);
            // 搜索
            TopDocs topDocs = searcher.search(query, 10);
            System.out.println("本次搜索共" + topDocs.totalHits + "条数据");
            
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                // 获取文档编号
                int docID = scoreDoc.doc;
                Document doc = reader.document(docID);
                System.out.println("id: " + doc.get("id"));
                
                String title = doc.get("title");
                // 用高亮工具处理普通的查询结果,参数:分词器,要高亮的字段的名称,高亮字段的原始值
                String hTitle = highlighter.getBestFragment(new IKAnalyzer(), "title", title);
                
                System.out.println("title: " + hTitle);
                // 获取文档的匹配度
                System.out.println("匹配度:" + scoreDoc.score);
            }
        }

    排序:

        // 排序
        @Test
        public void testSortQuery() throws Exception {
            // 目录对象
            Directory directory = FSDirectory.open(new File("H:\test"));
            // 创建读取工具
            IndexReader reader = DirectoryReader.open(directory);
            // 创建搜索工具
            IndexSearcher searcher = new IndexSearcher(reader);
            
            QueryParser parser = new QueryParser("title", new IKAnalyzer());
            Query query = parser.parse("谷歌地图");
            
            // 创建排序对象,需要排序字段SortField,参数:字段的名称、字段的类型、是否反转如果是false,升序。true降序
            Sort sort = new Sort(new SortField("id", Type.LONG, true));
            // 搜索
            TopDocs topDocs = searcher.search(query, 10,sort);
            System.out.println("本次搜索共" + topDocs.totalHits + "条数据");
            
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            for (ScoreDoc scoreDoc : scoreDocs) {
                // 获取文档编号
                int docID = scoreDoc.doc;
                Document doc = reader.document(docID);
                System.out.println("id: " + doc.get("id"));
                System.out.println("title: " + doc.get("title"));
            }
        }

    分页:

        @Test
        public void testPageQuery() throws Exception {
            // 实际上Lucene本身不支持分页。因此我们需要自己进行逻辑分页。我们要准备分页参数:
            int pageSize = 2;// 每页条数
            int pageNum = 3;// 当前页码
            int start = (pageNum - 1) * pageSize;// 当前页的起始条数
            int end = start + pageSize;// 当前页的结束条数(不能包含)
            
            // 目录对象
            Directory directory = FSDirectory.open(new File("H:\test"));
            // 创建读取工具
            IndexReader reader = DirectoryReader.open(directory);
            // 创建搜索工具
            IndexSearcher searcher = new IndexSearcher(reader);
            
            QueryParser parser = new QueryParser("title", new IKAnalyzer());
            Query query = parser.parse("谷歌地图");
            
            // 创建排序对象,需要排序字段SortField,参数:字段的名称、字段的类型、是否反转如果是false,升序。true降序
            Sort sort = new Sort(new SortField("id", Type.LONG, false));
            // 搜索数据,查询0~end条
            TopDocs topDocs = searcher.search(query, end,sort);
            System.out.println("本次搜索共" + topDocs.totalHits + "条数据");
            
            ScoreDoc[] scoreDocs = topDocs.scoreDocs;
            for (int i = start; i < end; i++) {
                ScoreDoc scoreDoc = scoreDocs[i];
                // 获取文档编号
                int docID = scoreDoc.doc;
                Document doc = reader.document(docID);
                System.out.println("id: " + doc.get("id"));
                System.out.println("title: " + doc.get("title"));
            }
        }

    加权因子:

    • Lucene会对搜索的结果的匹配度进行一个加分, 用来表示数据和词条关联性的强弱, 得分越高, 表示匹配度越高, 排名越靠前

    • Lucene支持对某一个字段设置加权因子, 来提高其打分, 使其排名更加靠前, 这样当用户搜索的时候, 便可以将此词条对应的文档展示在最前面

    TextField textField = new TextField("content","lucene加权因子", Store.YES);
    textField.setBoost(10);
  • 相关阅读:
    利用 FFmpeg 和 ImageMagick, AVI 转 GIF(不失真)
    TinyMCE textarea 输入框外部程序动态修改方法
    eclipse快速向下复制行
    ${factoryList }后面有空格不影响
    pre标签
    js备忘录_2
    eclipse 中 大小写切换:ctrl+shift+x 转为大写 ctrl+shift+y 转为小写
    js备忘录_1
    缓存
    myeclipse bug
  • 原文地址:https://www.cnblogs.com/blazeZzz/p/9436129.html
Copyright © 2020-2023  润新知