Lucene之分页查询的三种方式-yellowcong
来源:互联网 发布:淘宝千里眼软件 编辑:程序博客网 时间:2024/05/17 22:48
分页查询有三种,一种是直接查询出这页及这页以后的数据,第二种,查询这页以前的最后一条数据,然后再查询这页之后的数据,这种方式还不如第一种方法快,第三种,是根据一个id来进行分页,这种方式适合不变更的数据
方法1
思路是将所有的查询取来,然后取自己当前页需要的数据
/** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午3:37:17<br/> * 机能概要: 查询所有数据后再进行分页 */ public static void queryByPager1(int pageNow,int pageSize){ IndexReader reader = null; try { reader = getIndexReader(); QueryParser parser = new QueryParser(Version.LUCENE_45, "content",new StandardAnalyzer(Version.LUCENE_45)); Query query = parser.parse("username:yellow*"); //创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); //查询数据, 结束页面自前的数据都会查询到,但是只取本页的数据 TopDocs topDocs = searcher.search(query, pageSize*pageNow); System.out.println("查询到的条数\t"+topDocs.totalHits); ScoreDoc [] scores = topDocs.scoreDocs; int start = (pageNow -1)*pageSize ; int end = pageSize*pageNow; for(int i=start;i<end;i++){ Document doc = reader.document(scores[i].doc); System.out.println(doc.get("id")+":"+doc.get("username")+":"+doc.get("email")); } } catch (Exception e) { e.printStackTrace(); }finally{ coloseReader(reader); } }
方法2
第二个方法,就是先获取前一条的记录(ScoreDoc),然后IndexSearcher.searchAfter
再获取后面的记录
/** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午3:54:55<br/> * 机能概要:通过IndexSearcher.searchAfter * * @param pageNow * @param pageSize */ public static void queryByPager2(int pageNow, int pageSize) { IndexReader reader = null; try { reader = getIndexReader(); QueryParser parser = new QueryParser(Version.LUCENE_45, "content", new StandardAnalyzer(Version.LUCENE_45)); Query query = parser.parse("username:yellow*"); // 创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); int start = (pageNow - 1) * pageSize; // 查询数据, 结束页面自前的数据都会查询到,但是只取本页的数据 TopDocs topDocs = searcher.search(query, start); //获取到上一页最后一条 ScoreDoc preScore = topDocs.scoreDocs[start-1]; //查询最后一条后的数据的一页数据 topDocs = searcher.searchAfter(preScore, query, pageSize); ScoreDoc[] scores = topDocs.scoreDocs; System.out.println("查询到的条数\t" + topDocs.totalHits); //读取数据 for (int i = 0; i < scores.length; i++) { Document doc = reader.document(scores[i].doc); System.out.println(doc.get("id") + ":" + doc.get("username") + ":" + doc.get("email")); } } catch (Exception e) { e.printStackTrace(); } finally { coloseReader(reader); } }
方法3
通过Id的方式来解决这个问题,但是id这种查询方式需要注意的是只能对不变化的数据,通过id分页,但是不能对其他的条件进行分页
/** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午2:38:27<br/> * 机能概要:分页查询 * * @param pageSize * @param pageNow * @throws Exception */ public static void queryByPager3(int pageNow, int pageSize) { IndexReader reader = null; try { reader = getIndexReader(); Query query = NumericRangeQuery.newIntRange("id", (pageNow - 1) * pageSize + 1, pageNow * pageSize, true, true); // 创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); // 查询数据 TopDocs topDocs = searcher.search(query, pageSize); for (ScoreDoc score : topDocs.scoreDocs) { Document doc = reader.document(score.doc); System.out.println(doc.get("id") + ":" + doc.get("username") + ":" + doc.get("email")); } } catch (Exception e) { e.printStackTrace(); } finally { coloseReader(reader); } }
完整代码
package com.yellowcong.demo;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Date;import java.util.List;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.IntField;import org.apache.lucene.document.LongField;import org.apache.lucene.document.StringField;import org.apache.lucene.document.TextField;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.index.Term;import org.apache.lucene.queryparser.classic.QueryParser;import org.apache.lucene.search.FuzzyQuery;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.NumericRangeQuery;import org.apache.lucene.search.PhraseQuery;import org.apache.lucene.search.PrefixQuery;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TermQuery;import org.apache.lucene.search.TopDocs;import org.apache.lucene.search.WildcardQuery;import org.apache.lucene.store.FSDirectory;import org.apache.lucene.util.Version;/** * 创建用户:狂飙的yellowcong<br/> * 创建时间:下午5:27:50<br/> * 创建日期:2017年12月2日<br/> * 机能概要: */public class Demo6 { private static List<Passage> psgList = null; // 写对象 private static IndexWriter writer = null; public static void main(String[] args) throws Exception { // 删除 所有索引 deleteAll(); // 建立索引 index(); queryByPager3(3, 10); } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午3:54:55<br/> * 机能概要:通过IndexSearcher.searchAfter * * @param pageNow * @param pageSize */ public static void queryByPager2(int pageNow, int pageSize) { IndexReader reader = null; try { reader = getIndexReader(); QueryParser parser = new QueryParser(Version.LUCENE_45, "content", new StandardAnalyzer(Version.LUCENE_45)); Query query = parser.parse("username:yellow*"); // 创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); int start = (pageNow - 1) * pageSize; // 查询数据, 结束页面自前的数据都会查询到,但是只取本页的数据 TopDocs topDocs = searcher.search(query, start); //获取到上一页最后一条 ScoreDoc preScore = topDocs.scoreDocs[start-1]; //查询最后一条后的数据的一页数据 topDocs = searcher.searchAfter(preScore, query, pageSize); ScoreDoc[] scores = topDocs.scoreDocs; System.out.println("查询到的条数\t" + topDocs.totalHits); //读取数据 for (int i = 0; i < scores.length; i++) { Document doc = reader.document(scores[i].doc); System.out.println(doc.get("id") + ":" + doc.get("username") + ":" + doc.get("email")); } } catch (Exception e) { e.printStackTrace(); } finally { coloseReader(reader); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午3:37:17<br/> * 机能概要: 查询所有数据后再进行分页 */ public static void queryByPager1(int pageNow, int pageSize) { IndexReader reader = null; try { reader = getIndexReader(); QueryParser parser = new QueryParser(Version.LUCENE_45, "content", new StandardAnalyzer(Version.LUCENE_45)); Query query = parser.parse("username:yellow*"); // 创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); // 查询数据, 结束页面自前的数据都会查询到,但是只取本页的数据 TopDocs topDocs = searcher.search(query, pageSize * pageNow); // searcher.searchAfter(after, query, n) System.out.println("查询到的条数\t" + topDocs.totalHits); ScoreDoc[] scores = topDocs.scoreDocs; int start = (pageNow - 1) * pageSize; int end = pageSize * pageNow; for (int i = start; i < end; i++) { Document doc = reader.document(scores[i].doc); System.out.println(doc.get("id") + ":" + doc.get("username") + ":" + doc.get("email")); } } catch (Exception e) { e.printStackTrace(); } finally { coloseReader(reader); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午2:38:27<br/> * 机能概要:分页查询 * * @param pageSize * @param pageNow * @throws Exception */ public static void queryByPager3(int pageNow, int pageSize) { IndexReader reader = null; try { reader = getIndexReader(); Query query = NumericRangeQuery.newIntRange("id", (pageNow - 1) * pageSize + 1, pageNow * pageSize, true, true); // 创建IndexSearcher IndexSearcher searcher = new IndexSearcher(reader); // 查询数据 TopDocs topDocs = searcher.search(query, pageSize); for (ScoreDoc score : topDocs.scoreDocs) { Document doc = reader.document(score.doc); System.out.println(doc.get("id") + ":" + doc.get("username") + ":" + doc.get("email")); } } catch (Exception e) { e.printStackTrace(); } finally { coloseReader(reader); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:下午12:01:55<br/> * 机能概要:查询Query 将需要查询的条件传递进来 * * @param query */ public static void excQuery(Query query) { // 查询 IndexReader reader = null; try { reader = getIndexReader(); // 获取查询数据 IndexSearcher searcher = new IndexSearcher(reader); // 检索数据 TopDocs topDocs = searcher.search(query, 100); for (ScoreDoc scoreDoc : topDocs.scoreDocs) { // 湖区偶 Document doc = reader.document(scoreDoc.doc); System.out.println(doc.get("id") + ":" + doc.get("username") + ":" + doc.get("email")); } } catch (Exception e) { e.printStackTrace(); } finally { coloseReader(reader); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月3日<br/> * 创建时间:上午11:52:52<br/> * 机能概要:关闭IndexReader * * @param reader */ private static void coloseReader(IndexReader reader) { try { if (reader != null) { reader.close(); } } catch (IOException e) { e.printStackTrace(); } } static { psgList = new ArrayList<Passage>(); // 产生一堆数据 for (int i = 1; i <= 200; i++) { psgList.add(new Passage(i, "yellowcong", "717350389@qq.com", "逗比", 23, "I LOVE YOU ", new Date())); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午5:43:57<br/> * 机能概要:获取IndexWriter 同一时间 ,只能打开一个 IndexWriter,独占写锁 。内建线程安全机制。 * * @return * @throws Exception */ @SuppressWarnings("static-access") public static IndexWriter getIndexWriter() throws Exception { // 创建IdnexWriter String path = getIndexPath(); FSDirectory fs = FSDirectory.open(new File(path)); // 判断资源是否占用 if (writer == null || !writer.isLocked(fs)) { synchronized (Demo3.class) { if (writer == null || !writer.isLocked(fs)) { // 创建writer对象 writer = new IndexWriter(fs, new IndexWriterConfig(Version.LUCENE_45, new StandardAnalyzer(Version.LUCENE_45))); } } } return writer; } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午5:46:36<br/> * 机能概要:获取到IndexReader 任意多个IndexReaders可同时打开,可以跨JVM。 * * @return * @throws Exception */ public static IndexReader getIndexReader() throws Exception { // 创建IdnexWriter String path = getIndexPath(); FSDirectory fs = FSDirectory.open(new File(path)); // 获取到读 return IndexReader.open(fs); } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午7:57:04<br/> * 机能概要:删除所有的索引 */ public static void deleteAll() { IndexWriter writer = null; try { // 获取IndexWriter writer = getIndexWriter(); // 删除所有的数据 writer.deleteAll(); int cnt = writer.numDocs(); System.out.println("索引条数\t" + cnt); // 提交事物 writer.commit(); } catch (Exception e) { e.printStackTrace(); } finally { coloseWriter(writer); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午5:37:22<br/> * 机能概要:获取索引目录 * * @return 目录 */ private static String getIndexPath() { // 获取索引的目录 String path = Demo3.class.getClassLoader().getResource("index").getPath(); // 不存在就创建目录 File file = new File(path); if (!file.exists()) { file.mkdirs(); } return path; } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午8:24:16<br/> * 机能概要:关闭IndexWriter */ private static void coloseWriter(IndexWriter writer) { try { if (writer != null) { writer.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午8:26:15<br/> * 机能概要:关闭IndexReader * * @param reader */ public static void closerReader(IndexReader reader) { try { if (reader != null) { reader.close(); } } catch (IOException e) { e.printStackTrace(); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午8:10:01<br/> * 机能概要: 查询数据 * * @param key * 查询范围 * @param val * 值 */ public static void search(String key, Object val) { IndexReader reader = null; try { reader = getIndexReader(); IndexSearcher searcher = new IndexSearcher(reader); // 精确查询 Query query = null; // 定义查询条件 if (val instanceof Integer) { // 后面的两个true 表示的是 是否包含 上下的数据 query = NumericRangeQuery.newIntRange(key, Integer.parseInt(val.toString()), Integer.parseInt(val.toString()), true, true); } else { query = new TermQuery(new Term(key, val.toString())); } // QueryParser paraser = new QueryParser(Version.LUCENE_45, key, new // StandardAnalyzer(Version.LUCENE_45)); // Query query = paraser.parse(val); // 获取查询到的Docuemnt TopDocs topDocs = searcher.search(query, 500); // 总共命中的条数 System.out.println(topDocs.totalHits); for (ScoreDoc score : topDocs.scoreDocs) { // Document doc = searcher.doc(score.doc); // 查询到的结果 String username = doc.get("username"); System.out.println(username); } } catch (Exception e) { e.printStackTrace(); } finally { closerReader(reader); } } /** * 创建用户:狂飙的yellowcong<br/> * 创建日期:2017年12月2日<br/> * 创建时间:下午6:03:33<br/> * 机能概要:建立索引 */ public static void index() { IndexWriter writer = null; try { // 1、获取IndexWriter writer = getIndexWriter(); // 2、建立索引 for (Passage psg : psgList) { Document doc = new Document(); // IntField 不能直接检索到,需要结合 doc.add(new IntField("id", psg.getId(), Field.Store.YES)); // 用户String类型的字段的存储,StringField是只索引不分词 doc.add(new TextField("username", psg.getUsername(), Field.Store.YES)); // 主要对int类型的字段进行存储,需要注意的是如果需要对InfField进行排序使用SortField.Type.INT来比较,如果进范围查询或过滤,需要采用NumericRangeQuery.newIntRange() doc.add(new IntField("age", psg.getAge(), Field.Store.YES)); // 对String类型的字段进行存储,TextField和StringField的不同是TextField既索引又分词 doc.add(new TextField("content", psg.getContent(), Field.Store.NO)); doc.add(new StringField("keyword", psg.getKeyword(), Field.Store.YES)); doc.add(new StringField("email", psg.getEmail(), Field.Store.YES)); // 日期数据添加索引 doc.add(new LongField("addDate", psg.getAddDate().getTime(), Field.Store.YES)); // 3、添加文档 writer.addDocument(doc); } // 索引条数 int cnt = writer.numDocs(); System.out.println("索引条数\t" + cnt); // 提交事物 writer.commit(); } catch (Exception e) { e.printStackTrace(); } finally { coloseWriter(writer); } } static class Passage { private int id; private String username; private String email; private String keyword; private int age; // 这个模拟的是文章 private String content; private Date addDate; public Passage(int id, String username, String email, String keyword, int age, String content, Date addDate) { super(); this.id = id; this.username = username; this.email = email; this.keyword = keyword; this.age = age; this.content = content; this.addDate = addDate; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getKeyword() { return keyword; } public void setKeyword(String keyword) { this.keyword = keyword; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Date getAddDate() { return addDate; } public void setAddDate(Date addDate) { this.addDate = addDate; } }}
阅读全文
0 0
- Lucene之分页查询的三种方式-yellowcong
- Dubbo之服务运行的三种方式-yellowcong
- Solr之分页查询-yellowcong
- Lucene的分页查询
- Lucene的分页查询
- Lucene之模糊、精确、匹配、范围、多条件查询-yellowcong
- JavaWeb分页显示内容之分页查询的三种思路(数据库分页查询)
- JavaWeb分页显示内容之分页查询的三种思路(数据库分页查询)
- JavaWeb分页显示内容之分页查询的三种思路(数据库分页查询)
- Oracle分页查询三种方式
- Oracle分页查询三种方式
- oracle分页查询三种方式
- Spring-Mvc之表单验证的两种方式-yellowcong
- Lucene之入门案例-yellowcong
- Lucene之索引的创建和域选项-yellowcong
- Lucene之索引的增删改查-yellowcong
- Shiro之授权管理与授权的三种方式(1、编程方式,2、注解方式,3、jsp标签)-yellowcong
- Lucene代码备份之分页条件查询
- HTML-列表篇
- Firewall
- 实验测试1《C++ Primer》第五版——第十三章 拷贝控制
- linux系统下openVPN的使用
- Utunbu16.04安装后的系统整理及常用软件安装
- Lucene之分页查询的三种方式-yellowcong
- C51(AT89C52)同济大学出版社《单片机原理及应用》(魏鸿磊)第六章第12题答案
- 读书笔记《C++ Primer》第五版——第十四章 重载运算与类型转换
- HDU1213 How Many Tables (并查集)
- 图片内存计算大小
- Mybatis框架搭建
- 【Scikit-Learn 中文文档】 16 半监督学习
- Server Tomcat v7.0 Server at localhost failed to start.解决办法
- 实验测试1《C++ Primer》第五版——第十四章 重载运算与类型转换