市长信箱邮件查询服务: 使用Elasticsearch 替代 Mysql

瘢结枚举
• 阅读 3115

市长信箱邮件查询服务: 使用Elasticsearch 替代 Mysql

我在上一篇文章中实现了一个基于Springboot构建的web应用: 市长信箱邮件查询服务. 应用将邮件信息抓取后保存在Mysql中,用以提供给搜索Web使用.Mysql虽然集成简单,能快速实现功能, 但like查询性能一般, 尤其数据量大了之后就必须考虑使用搜索引擎. 所以这次我把存储从Mysql替换为Elasticsearch(ES).


Elasticsearch提供了两种方式API来进行调用: Rest API与Java Native. Java Native的执行效率更高, 并且与当前项目集成更方便,所以我这里选择了Java native Api. 引入Java native Api,只需要在根pom.xml添加依赖:

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>2.3.3</version>
</dependency>

使用ES替换Mysql,需要考虑这两方面:

  1. 存储: 将Mysql的insert插入数据改为ES的添加文档操作.

  2. 查询: 替换Mysql的查询sql语句,改为ES的搜索操作.

存储:

由于我们的邮件结构简单,没有内嵌其他复杂对象, 所以从mysql转换为ES的文档非常自然. 只需调用ES的添加文档API即可:

public static void indexMails(Iterable<Mail> mails) {
    BulkRequestBuilder bulkRequest = client.prepareBulk();
    for (Mail mail : mails) {
        addMailIndexRequest(bulkRequest, mail);
    }
    BulkResponse bulkResponse = bulkRequest.get();
    System.out.println(JSON.toJSONString(bulkResponse));
}

private static void addMailIndexRequest(BulkRequestBuilder bulkRequest, Mail mail) {
    try {
        bulkRequest.add(client.prepareIndex("chengdu12345", "mail")
            .setSource(XContentFactory.jsonBuilder()
                .startObject()
                .field("content", mail.content)
                .field("createDate", mail.createDate)
                .field("acceptUnit", mail.acceptUnit)
                .field("category", mail.category)
                .field("result", mail.result)
                .field("sender", mail.sender)
                .field("status", mail.status)
                .field("title", mail.title)
                .field("url", mail.url)
                .field("views", mail.views)
                .endObject())
        );
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

在以上代码中,我使用了批量添加(bulkRequest)API, 以减少API调用次数.

查询:

之前Mysql中邮件的查询sql如下:

select m from cheng12345 m where m.title like ? or m.content like ? or m.result like ? order by create_date desc limit ?,?

用ES来实现SQL对应效果的代码也非常简单:

public static SearchHits searchByKeyword(String keyword, int from, int size) {
    SearchRequestBuilder request = client.prepareSearch("chengdu12345")
            .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
            .setQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content", "result")
            .type(MatchQueryBuilder.Type.PHRASE))//完全匹配
            .addSort("createDate", SortOrder.DESC)
            .setFrom(from).setSize(size).setExplain(true);

    SearchResponse response = request.execute().actionGet();
    return response.getHits();
}

这里需要注意的是,查询类型我选择的是短语查询(Type.PHRASE), 它能保证搜索时输入的短语不被拆分, 否则我输入"红牌楼"查询时,可能返回一堆包含"红楼"的邮件列表, 这明显不是我想要的结果.

另外, Springdata同样提供了对ES的支持, 它像对JPA一样提供了基于Repository模板方法支持,利用它能简化不少对ES操作的代码.

点赞
收藏
评论区
推荐文章
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
liuzhen007 liuzhen007
4年前
nslookup命令使用技巧【珍藏版】
目录前言正文一、缺省查询二、指定DNS查询三、查询命名服务器四、反向解析域名五、查询邮件服务器信息前言nslookup是一个DNS查询工具,可以指定查询的类型,可以查到DNS记录的生存时间,还可以指定使用那个DNS服务器进行解释。正文一、缺省查询不指定dnsserver,使用系统默认的dns服务器。 命令:nslookup域名实例:
Stella981 Stella981
4年前
Spring Boot + Elasticsearch实现大批量数据集下中文的精确匹配
缘由数据存储在MYSQ库中,数据基本维持不变,但数据量又较大(几千万)放在MYSQL中查询效率上较慢,寻求一种简单有效的方式提高查询效率,MYSQL并不擅长大规模数据量下的数据查询。技术方案考虑后期同样会使用到es,此次直接结合springboot框架形成一个独立服务,并不涉及UI展现内容,(ES版本2.4.5,5.0版本的话
Wesley13 Wesley13
4年前
MySQL千万级别优化·中
MySQL千万级别的查询优化手段·中单列索引(假设在v\_record表中存在id列的索引)1、WHERE条件使用​EXPLAINSELECT\FROMv\_recordWHEREid2​结论:利用索引进行回表查询2、SELECT字段使用
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
4年前
Logstash提取ES中的堆栈后合并输出到邮件或者控制台
核心流程1.利用logstash查询Elasticsearch.2.再利用match,mutate提取必要信息.3.之后利用ruby执行本地shell或者命令获取输出返回值4.利用aggregate将多个event合并为一个5.最后发送邮件或者输出注意,es查询到多条数据在logstash中算是多个event.
Wesley13 Wesley13
4年前
mysql5.6 分页查询优化
mysql5.6分页查询优化场景:表结构:主键(非自增)contentCode(varchar),过滤条件列为updateTime(timeStamp),已经为timestamp建立索引。搜索sql为:SELECTFROMmy_hello_tableWHEREupdat
Stella981 Stella981
4年前
Linux中Postfix邮件WebMail配置(七)
ExtmailExtmail是一个以perl语言编写,面向大容量/ISP级应用,免费的高性能Webmail软件,主要包括ExtMail、Extman两个部分的程序套件。ExtMail套件用于提供从浏览器中登录、使用邮件系统的Web操作界面,提供给普通邮件用户使用。而Extman套件用于提供从浏览器中管理邮件系统的Web操作界面,提供给邮件系统的
Stella981 Stella981
4年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
瘢结枚举
瘢结枚举
Lv1
回忆总是会打我一个巴掌指着旧的伤疤不准我遗忘
文章
3
粉丝
0
获赞
0