Lucene查询数据的相关度排序问题
来源:互联网 发布:手机调音量软件 编辑:程序博客网 时间:2024/06/01 13:00
Lucene查询出来的数据排序有两个方面会影响到,
一是tf(Term frequency), 查询的关键字在当前文档中出现 的次数越多,权重越高,排名越靠前
二是df(Document frequency),查询的关键字在多个文档中出现的资料越多,权重相对较低。
那么查询出来的数据是否可以人为影响排序呢? 答案是可以的,总共有两种方式。
一是在创建索引时,设置boost参数:
/** * 创建索引时,对指定数据设置影响排序的参数 * @创建时间:2017年10月8日16:17:21 */ @Test public void zfIndex() throws IOException{ //创建写入流,并指定分词器、索引目录 Directory directory = FSDirectory.open(new File("D:"+File.separator+"lucene_index"+File.separator)); IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, new StandardAnalyzer()); IndexWriter writer = new IndexWriter(directory, config); //从数据库获取数据 BookDao dao = new BookDaoImpl(); List<Book> books = dao.queryBooks(); //创建集合中,用以保存要存储到索引文档中的内容 List<Document> documents = new ArrayList<>(); Document document ; for(Book book : books){ document = new Document(); //创建索引域及相关内容 Field id = new StringField("id", book.getId().toString(), Store.YES); Field name = new TextField("name", book.getName(), Store.YES); Field price = new FloatField("price", book.getPrice(), Store.YES); Field pic = new StringField("pric", book.getPic(), Store.YES); Field description = new TextField("description", book.getDescription(),Store.YES); //设置boost参数,会影响到它的排序,但注意,在TextField上可以设置boost,StringField、StoreField上不能设置 if(book.getId() == 5){ description.setBoost(100f); } //创建一个document文档内容 document.add(id); document.add(name); document.add(price); document.add(pic); document.add(description); //将当前文档内容写入到集合中 documents.add(document); } //将集合中的数据写入索引文件 for(Document doc : documents){ writer.addDocument(doc); } //关闭流 writer.close(); }
第二种是在查询时设置参数,只在MultiFieldQueryParser 对象中生效
/** * 查询lucene索引数据 @创建时间:2017年10月7日22:57:00 */ public void query(Query query) { try { // 指定查询的索引目录 Directory directory = FSDirectory.open(new File("D:" + File.separator + "lucene_index" + File.separator)); // 创建流对象 IndexReader reader = DirectoryReader.open(directory); // 通过流对象创建索引搜索对象 IndexSearcher searcher = new IndexSearcher(reader); // 将查询到的指定索引域数据赋值给TopDocs TopDocs topDocs = searcher.search(query, 10); // 根据获取查询到的总数据 int totalHits = topDocs.totalHits; // 输出 System.out.println("共查询到数据总数为:" + totalHits); System.out.println(); // 将查询到的索引数据赋值给数组 ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 如果未查询到数据,则输出提示 if (scoreDocs == null || scoreDocs.length == 0) { System.out.println("未查询到数据"); } else { // 如果查询到的有数据。则循环输出 for (ScoreDoc doc : scoreDocs) { // 获取索引ID int docID = doc.doc; // 根据索引数据查询文档中对应的数据 Document document = searcher.doc(docID); // 将查询到的数据输出 System.out.println("ID:" + document.get("id")); System.out.println("name:" + document.get("name")); System.out.println("price:" + document.get("price")); System.out.println("pic:" + document.get("pic")); System.out.println("description:" + document.get("description")); System.out.println("=================================="); System.out.println(); System.out.println(); } } // 关闭流 reader.close(); } catch (IOException e) { e.printStackTrace(); } }/** * 要查询时,使用Map<String, Float> boosts 设置查询结 * 果的排序 * 只有在MultiFieldQueryParser 中才可以使用 * @创建时间:2017年10月8日16:27:42 */ @Test public void testSeracher() throws ParseException{ //查询的多个索引域名称 String[] fields = {"name","description"}; //分词器 Analyzer analyzer = new StandardAnalyzer(); //以下设置的效果:当搜索的关键字在name存在时,会优先将name包含关键字的内容排序在最前面 Map<String, Float> boosts = new HashMap<String,Float>(); boosts.put("name", 200f); //多域查询对象 MultiFieldQueryParser parser= new MultiFieldQueryParser(fields, analyzer, boosts); //设置查询条件 Query query = parser.parse("lucene"); //查询 query(query);
结果如下,可以发现name包含lucene关键字的数据排在了第一位:
共查询到数据总数为:2ID:1name:java luceneprice:11.23pic:nulldescription:给你推荐一个写得非常用心的Java基础教程:Java入门基础教程 | 天码营这个教程将Java的入门基础知识贯穿在一个实例中,逐步深入,可以帮助你快速进入Java编程的世界。万事开头难,逐步跟着这个教程走一遍,对Java应该就会有一种入门的感觉了。然后再去学习更高级的主题,或者更深入地学习其中的某些知识点。第1课 Java开发环境安装与配置 第2课 第一个Java程序 第3课 面向对象基础 第4课 基本数据类型 第5课 运算符 第6课 字符串操作 第7课 程序的控制流 第8课 静态变量与静态方法 第9课 Java集合 第10课 封装与继承 第11课 抽象类与接口 第12课 异常处理 第13课 综合实例 第14课 Eclipse的安装与使用作者:David链接:https://www.zhihu.com/question/25255189/answer/86898400来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。==================================ID:2name:solx price:12.55pic:nulldescription:Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。[1] ==================================
阅读全文
0 0
- Lucene查询数据的相关度排序问题
- Lucene相关度排序
- Lucene教程--维护索引、查询对象和相关度排序
- Lucene相关度排序的调整
- Lucene相关度排序的调整
- Lucene 的查询方式|排序
- 关于Lucene分组查询后的排序
- 相关子查询影响排序数据返回的排列
- Lucene--相关度排序和中文分析器
- lucene 3(相关度排序)
- lucene 查询+分页+排序
- access 数据查询中碰到的日期相关的问题
- activerecord 数据查询与排序相关
- JAVAWEB开发之Lucene详解——Lucene入门及使用场景、全文检索、索引CRUD、优化索引库、分词器、高亮、相关度排序、各种查询
- lucene排序---相关度与其他组合排序
- lucene排序---相关度与其他组合排序
- android中Sqlite查询的数据返回排序问题
- lucene 排序问题
- 动态规划-122. Best Time to Buy and Sell Stock II
- hdu 1531(差分约束)
- Leaflet入门之地图显示
- 例题6-8 二叉树的递归遍历 uva548
- 编辑联系5
- Lucene查询数据的相关度排序问题
- 十八岁的我们
- Portlet 通信(四) 利用事件传递参数
- Face Recognition(face_recognition) Using Hadoop Streaming API
- Nginx源码编译安装
- 最近收集的中科院研究生教学视频
- git添加远程库
- 如何让 vim 成为我们的神器
- CNN的全面解析