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支持对某一个字段设置加权因子, 来提高其打分, 使其排名更加靠前, 这样当用户搜索的时候, 便可以将此词条对应的文档展示在最前面
TextField textField = new TextField("content","lucene加权因子", Store.YES); textField.setBoost(10);