lucene学习记录(3) - 结果排序, 范围查询_lucene 范围查询-程序员宅基地

技术标签: Java  学习  mybatis  lucene  

前言

推荐Lucene文章, 也是本人上一篇博客里提到的
这次是系列文章<<Lucene 6.0实战>>,  传送门

结果排序

应业务需求, 要把上一篇文章中的结果按照排序(文字的发布时间)
所以Document要增加一个time字段
对于时间上的比较, 本人倾向于用时间戳, 毕竟文本的表达方式比较起来效率不高
SO, 规定time为long型, 意义为unixTime
然后在search的时候
final static Sort sort = new Sort(new SortField(TIME_COLUMN, SortField.Type.LONG, true));
在search的时候带上这个sort就会把结果按照时间从大到小排序了

范围查询

这里的范围是指时间范围, 即指定搜索某一时间到某一时间内的数据
由于刚才提到了用long来记录时间, 所以在限定结果范围的时候也要用这个类型
Query query = LongPoint.newRangeQuery("字段", 下限, 上限);
用这个query去search即可

复合查询

每一种查询只能限定一种条件, 那多种查询的组合就要用BooleanQuery来搞定了
把各个查询添加到BooleanQuery中去, 再生成一个Query对象, 然后search
这里需要注意的是, 添加到BooleanQuery的子查询必须也是BooleanQuery, 否则有问题(这个坑我爬了半小时)
BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
queryBuilder.add(......);
TopDocs docs = searcher.search(queryBuilder.build(), count);
 

测试代码

需求: 
在某个时间范围内, 根据关键字搜索出N个数据(含有任一关键字即可), 并把结果按照时间排序
public class LuceneManager {

    final static String ID_COLUMN = "id";
    final static String ITEM_COLUMN = "item";
    final static String TIME_COLUMN = "time";

    final static Analyzer analyzer = new JcsegAnalyzer5X(JcsegTaskConfig.SIMPLE_MODE);
    final static Sort sort = new Sort(new SortField(TIME_COLUMN, SortField.Type.LONG, true));

    Directory dir;
    IndexWriter writer;

    public LuceneManager(Directory dir) throws IOException {
        this.dir = dir;
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        writer = new IndexWriter(dir, config);
    }

    @Override
    protected void finalize() throws Throwable {
        this.close();
        super.finalize();
    }

    public void close() throws IOException {
        if (writer != null) {
            writer.close();
            writer = null;
        }
    }

    public static List<String> analyse(String str) throws IOException {
        List<String> result = new ArrayList<>();

        TokenStream ts = analyzer.tokenStream("", str);
        ts.reset();
        try {
            ts.addAttribute(CharTermAttribute.class);
            while (ts.incrementToken()) {
                CharTermAttribute cta = ts.getAttribute(CharTermAttribute.class);
                result.add(new String(cta.buffer(), 0, cta.length()));
            }
        } finally {
            ts.close();
        }
        return result;
    }

    public Directory getDirectory() {
        return dir;
    }

    Document buildDocument(long id, String item, long unixTime) {
        Document doc = new Document();

        doc.add(new StoredField(ID_COLUMN, id));
        doc.add(new TextField(ITEM_COLUMN, item, Field.Store.NO));

        doc.add(new LongPoint(TIME_COLUMN, unixTime));// 用于查询的属性
        doc.add(new NumericDocValuesField(TIME_COLUMN, unixTime));// 用于排序的属性

        return doc;
    }

    Term buildTerm(long id) {
        return new Term("id", Long.toString(id));
    }

    public void append(long id, String item, long unixTime) throws IOException {
        writer.addDocument(buildDocument(id, item, unixTime));
    }

    public void delete(long id) throws IOException {
        writer.deleteDocuments(buildTerm(id));
    }

    public void update(long id, String item, long unixTime) throws IOException {
        writer.updateDocument(buildTerm(id), buildDocument(id, item, unixTime));
    }

    List<Long> buildSearchResult(IndexSearcher searcher, TopDocs topDocs) throws IOException {
        List<Long> result = new ArrayList<>();

        for (ScoreDoc sd : topDocs.scoreDocs) {
            Document doc = searcher.doc(sd.doc);
            IndexableField field = doc.getField(ID_COLUMN);
            long id = field.numericValue().longValue();

            result.add(id);
        }
        return result;
    }

    public List<Long> search(String keyWords[], int count, long startTime, long stopTime) throws IOException {
        IndexReader reader = DirectoryReader.open(writer);
        IndexSearcher searcher = new IndexSearcher(reader);

        try {
            BooleanQuery.Builder timeLimit = new BooleanQuery.Builder();
            timeLimit.add(LongPoint.newRangeQuery(TIME_COLUMN, startTime, stopTime), BooleanClause.Occur.MUST);

            BooleanQuery.Builder keysLimit = new BooleanQuery.Builder();
            for (String s : keyWords) {
                keysLimit.add(new TermQuery(new Term(ITEM_COLUMN, s)), BooleanClause.Occur.SHOULD);
            }

            // 查询条件:
            // if (时间范围内() && (有关键字1() || 有关键字2() || 有关键字3() || ...))
            BooleanQuery.Builder queryBuilder = new BooleanQuery.Builder();
            queryBuilder.add(timeLimit.build(), BooleanClause.Occur.MUST);
            queryBuilder.add(keysLimit.build(), BooleanClause.Occur.MUST);

            TopDocs docs = searcher.search(queryBuilder.build(), count, sort);
            return buildSearchResult(searcher, docs);
        } finally {
            reader.close();
        }
    }

    public List<Long> search(String keyWords[]) throws IOException {
        return search(keyWords, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE);
    }
}

调用代码和上一篇文章差不多, 不再浪费篇幅

结束语

TIME_COLUMN有俩属性, 一个用于限定范围查询, 一个用于排序
对于lucene理解的还很浅显, 若有错误, 请及时指出.
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Sidyhe/article/details/51838038

智能推荐

apache php html页面不显示内容,apache服务器下.htaccess控制文件列表、目录显示,不显示的方法...-程序员宅基地

文章浏览阅读348次。.htaccess文件不仅能控制伪静态、防盗链等等,它还具备控制项目文件在index.html或者index.php文件缺失时是否线上其他一些目录文件。我们经常能看到"forbidden You don't have permission to access / on this server" 这样的报错提示,那是因为我们关闭了服务器的目录索引。如果我们不关闭目录索引,那么基本上就把我们项目目录结..._阿帕奇已经把文件放在html文件夹里了但是就是看不到

线性回归原理----简单线性回归、多元线性回归_多元线性回归原理-程序员宅基地

文章浏览阅读6.5k次,点赞3次,收藏38次。回归分析是用来评估变量之间关系的统计过程。用来解释自变量X与因变量Y的关系。即当自变量X发生改变时,因变量Y会如何发生改变。线性回归是回归分析的一种,评估的自变量X与因变量Y之间是一种线性关系,当只有一个自变量时,成为简单线性回归,当具有多个变量时,称为多元线性回归。线性关系的理解:>画出来的图像是直的(简单线性回归是直线,多元线性回归是超平面)>每个自变量的最高次项为1拟合是指构建一种算法,使得该算法能够符合真实的数据。从机器学习角度讲,线性回归就是要构建一个线性函_多元线性回归原理

linux查看历史挂载饿磁盘,Linux 查看、挂载磁盘-程序员宅基地

文章浏览阅读636次。参考链接:https://www.cnblogs.com/youbiyoufang/p/7607174.htmldf -T 查看已挂载的分区和文件类型df 命令用于显示磁盘分区上的可使用的磁盘空间,-T 表示显示文件类型fdisk -l 可以显示出所有挂载和未挂载的分区,但不显示文件系统类型移动硬盘一般是/dev/sdX1的形式,比如/dev/sdc1。这里需要了解sdX1的含义,sd表示可移..._linux查看历史硬盘

php 老版本 下载地址,常用官方php版本下载链接-程序员宅基地

文章浏览阅读264次。【如何快速的开发一个完整的iOS直播app】&lpar;美颜篇&rpar;原文转自:袁峥Seemygo 感谢分享.自我学习 前言 在看这篇之前,如果您还不了解直播原理,请查看这篇文章如何快速的开发一个完整的iOS直播app(原理篇) 开发一款直播app,美颜功能是很重 ...cordova插件iOS平台实战开发注意点cordova插件是其设计理念的精髓部分,创建并使用自定义插..._php旧版本官方下载地址

【Java】HashMap 和 HashTable 的区别到底是什么?_java中hashmap和hashtable的区别-程序员宅基地

文章浏览阅读2.7w次,点赞21次,收藏48次。第一、继承不同第一个不同主要是历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。public class HashMap extends AbstractMap implements Cloneable, Serializable {...}public class Hashtable_java中hashmap和hashtable的区别

Openwrt下jshn.sh用法解析_json_get_vars-程序员宅基地

文章浏览阅读4.8k次,点赞3次,收藏11次。一、示例用到的json数据{ "up": true, "uptime": 18804, "l3_device": "eth0.2", "proto": "dhcp", "device": "eth0.2", "ipv4-address": [ { "address": "192.168.5.102", _json_get_vars

随便推点

Tips展开关闭问答代码_js tips 取消-程序员宅基地

文章浏览阅读351次。http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/1999/xhtml">无标题文档function show(c_Str,imgg){if(document.all(c_Str).style.display=='none'){document.all(c_Str)._js tips 取消

[Linux]grep指令加参数_grep 结果作为参数-程序员宅基地

文章浏览阅读2.2k次。1.grep指令的用途grep是我们常用的一个指令,经常与管道符“|”搭配,对上一操作的结果进行筛选通常我们是直接grep 内容例如:检查opt目录在不在 ll | grep opt查看tty相关进程ps -ef|grep tty检查22端口netstat -tunlp|grep 222.使用参数筛选在上面的操作中,可以看到查看进程和端口时,结果中多出了一些无关的东西在gr..._grep 结果作为参数

使用mycat搭建实现mysql数据库集群管理_mycat mysql集群-程序员宅基地

文章浏览阅读4.6k次,点赞4次,收藏18次。今天来使用mycat管理mysql集群, 随着数据量的提升, 我们如果把所有数据存储在一个数据库中, 对数据的各种操作就会变得非常的困难. 自然我们又想到了数据库也进行集群部署, 将一个数据库的数据分散到不同的数据库中存储, 进而提升数据操作的性能.本文的定义是简洁快速的使用mycat, 让读者可以快速的入门mycat, 因此本文聚焦于mycat的安装, 使用, 简易配置, 常用配置文件和标签的..._mycat mysql集群

python turtle画房子代码里面的窗子,如何用python画房子_用python画一个小房子-程序员宅基地

文章浏览阅读2.7k次。如何用python画一个小房子?效果图如下:代码如下:import turtle# 前置p = turtle.Pen()# 作者要说的话for i in range(6):print('请把画板最大化,否则会影响画面效果!')# 设置笔的速度p.speed(10)# 开始画画p.pencolor("#F4A460")p.penup()p.goto((-240), (-200))p.pendown(..._turtle 房子

linux 硬盘品牌,CentOS如何查看硬盘品牌型号等具体信息-程序员宅基地

文章浏览阅读3.5k次。首先使用smartctl --all /dev/sda指令来检查硬盘信息,该指令CentOS自带,得到的结果可能如下:smartctl 5.43 2012-06-30 r3573 [x86_64-linux-2.6.32-358.el6.x86_64] (local build)Copyright (C) 2002-12 by Bruce Allen, http://smartmontools...._centos查看物理机磁盘型号

腾讯计费平台部PHP,企业级正规php第三方api第四方支付平台程序源码完整开源全套 - A保站...-程序员宅基地

文章浏览阅读388次。程序名称:企业级PHP第三方支付平台(云计费聚合支付)程序语言:PHP+mysql程序大小:约180MB程序已集成支付宝PC、支付宝WAP、微信扫码、微信WAP、财付通PC、财付通WAP、QQ钱包扫码、QQ钱包WAP、银联在线、京东支付、环迅支付、易宝支付等等20多个接口。此套程序开发成本3万多,全站兼容手机HTML5页面,仅售2000元全套源码+数据库(包安装,,需要安装的联系卖家洽谈)官网演示..._api收费平台源码

推荐文章

热门文章

相关标签