使用ElasticSearch服务从MySQL同步数据实现搜索即时提示与全文搜索功能

摘要:
最近,为该公司的项目集成全文搜索引擎花了几天时间。该项目的初始目标是为搜索框提供即时提示。数据需要从MySQL同步。因为数据不小,所以需要在初始同步之后考虑连续增量同步。这里使用的开源服务是ElasticSearch。在网上了解后,我发现这是真的:全文搜索是最常见的需求,开源的Elasticsearch是目前全文搜索引擎的首选。有几种安装ElasticSearch的方法。就个人而言,我更喜欢CentOS yum从源代码安装。关键点是配置MySQL数据与Elastic的同步。配置MySQL数据库到Elastic的数据同步。

最近用了几天时间为公司项目集成了全文搜索引擎,项目初步目标是用于搜索框的即时提示。数据需要从MySQL中同步过来,因为数据不小,因此需要考虑初次同步后进行持续的增量同步。这里用到的开源服务就是ElasticSearch。

57936014e1fd3c061f51089804efd813.png

ElasticSearch是一个非常好用的开源全文搜索引擎服务,同事推荐之前我并没有了解过,但是看到亚马逊专门提供该服务的实例,没有多了解之前便猜想应该是和Redis一样名声在外的产品,估计也是经得起考验可以用在生产环境中了。上网了解一番之后发现果然如此:

全文搜索属于最常见的需求,开源的Elasticsearch是目前全文搜索引擎的首选。它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它。

废话不多说,按照惯例记录一下我的搭建过程。

安装ElasticSearch

安装有几种方式,我个人还是比较喜欢CentOS的yum从源安装。

CentOS的Yum方式安装

首先进入/etc/yum.repos.d目录,建立一个名为elasticsearch.repo的源,内容填写如下:

[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

这里Elastic目前最新版本为6.2,但与之对应的Elasticsearch-PHP需要PHP版本为7.0以上。由于公司的PHP版本是5.x,因此只有退而求其次,选择了稍微老一点的5.6.9版本,5.x版本的安装,只需要在这一步将上面源文件内容中的所有6.x换成5.x即可。

接下来执行

yum install elasticsearch

完成安装后,默认服务是仅仅本地可以访问,如果需要从另一台内网服务器访问,还需要打开监听范围。进入安装目录/usr/share/elasticsearch,编辑elasticsearch.yml文件,修改以下部分:

network.host: 0.0.0.0
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
http.host: 0.0.0.0
transport.host: 127.0.0.1

其中network.host是开启外部网络访问,而path.datapath.logs由于默认路径没有设置正确,这里需要手工设置一下。路径设置完成后需要确认一下这两个目录是否存在,如果目录内有上一次安装的残余内容,需要备份后清空,否则会引发一些问题。更多视频教程微信搜索:【码农编程进阶笔记】

接着重启服务:

service elasticsearch restart

安装完成测试

重启完成后,在浏览器中输入

http://127.0.0.1:9200/?pretty

如果能看到对应的信息,表示安装成功

安装LogStash

接着安装LogStash服务,这个服务用于汇总各类log日志信息到一个地方统一管理,而这里我们用到这个服务,是因为需要用它来实现数据从MySQL到Elastic的同步。

YUM方式安装LogStash

这同样是Elastic家的产品,因此包含在前面设置的源中,现在安装只需要执行:

yum install logstash

这样就完成了安装。接下来别急,还需要安装一个插件。

安装logstash-input-jdbc插件

首先进入/usr/share/logstash/bin目录,执行:

./logstash-plugin install logstash-input-jdbc

插件安装完成后,logstash的安装目前算是完成了。还有很多插件可以实现各种丰富的功能,而这里就咱不多说了。

配置同步MySQL数据到Elastic

接着就是比较重点的地方,配置数据从MySQL库同步到Elastic。首先在任意目录建立同步配置文件,我这里的同步脚本并不多,因此就直接把他们放在logstash的执行目录里:

cd /usr/share/logstash/bin

mkdir ktsee

cd ktsee

然后新建两个文件jdbc.confjdbc.sql,其中jdbc.conf是同步配置文件,jdbc.sql同步的mysql脚本。首先编辑jdbc.conf,填入内容:

input {
  stdin {
  }
  jdbc {
  # mysql jdbc connection string to our backup databse  后面的ktsee对应mysql中的test数据库
  jdbc_connection_string => "jdbc:mysql://192.168.1.1:3306/ktsee"
  # the user we wish to excute our statement as
  jdbc_user => "root"
  jdbc_password => "password"
  # the path to our downloaded jdbc driver 这里需要设置正确的mysql-connector-java-5.1.38.jar路径,找不到可以从网上下载后放在配置路径中
  jdbc_driver_library => "/elasticsearch-jdbc-2.3.2.0/lib/mysql-connector-java-5.1.38.jar"
  # the name of the driver class for mysql
  jdbc_driver_class => "com.mysql.jdbc.Driver"
  jdbc_paging_enabled => "true"
  jdbc_page_size => "50000"
# 以下对应着要执行的sql的绝对路径;更多视频教程微信搜索:【码农编程进阶笔记】
  statement_filepath => "/usr/local/logstash/bin/logstash_jdbc_test/jdbc.sql"
# 定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新
  schedule => "* * * * *"
# 设定ES索引类型
  type => "ktsee_type"
  }
}
filter {
  json {
  source => "message"
  remove_field => ["message"]
  }
}
output {
  elasticsearch {
#ESIP地址与端口
  hosts => "192.168.1.1:9200"
#ES索引名称(自己定义的)
  index => "ktsee_index"
#自增ID编号
  document_id => "%{id}"
  }
  stdout {
#以JSON格式输出
  codec => json_lines
  }
}

这里需要注意的地方,在上面配置文件中有相应的注释。

使用Elasticsearch-PHP库集成到项目中

这里选择使用Elasticsearch的官方PHP库Elasticsearch-PHP,如果项目使用composer进行包管理,那么很简单,直接安装对应的版本即可,composer会自动下载其他的依赖库。在项目中添加代码:

1$client = \Elasticsearch\ClientBuilder::create()
 2    ->setHosts(['192.168.1.1:9200'])
 3    ->allowBadJSONSerialization()
 4    ->build();
 5$params = [
 6    'index' => 'ktsee_index',
 7    '_source' => [
 8        "id",
 9        "product_name",
10        "product_type"
11    ],
12    'body' => [
13        'query' => [
14            'match_phrase_prefix' => [
15                'product_name' => [
16                    "query" => $post['keyword'],
17                    "slop" => 10
18                ]
19            ],
20        ]
21    ]
22];
23$response = $client->search($params);

这样就实现了简单的根据关键词搜索调用ElasticSearch

实现搜索即时提示代码

HTML部分:

1<form method="get" action="/search" id="header_search">
2    <input type="text" id="keyword" name="keyword" value="" autocomplete="off" />
3    <input type="submit" value="" />
4</form>
5<ul id="header_search_suggest"></ul>

这里值得注意的是,搜索框input控件加上autocomplete="off"关闭原生下拉提示框,避免和我们即将要做的智能提示冲突。

CSS部分:

#header_search_suggest{
    position: absolute;
     calc(100% - 10px);
    left: 4px;
    border: solid 1px #ccc;
    background-color: white;
    text-align: left;
    z-index: 101;
    display: none;
}
#header_search_suggest li{
    font-size: 14px;
    border-bottom: 1px solid #eeeeee;
}
#header_search_suggest li a{
    padding:0.5em 1em;
    color:#333333;
    display: block;
    text-decoration: none;
}
#header_search_suggest li a:hover{
    background-color: #EDF0F2;
    color:#2F7EC4;
}
#header_search_suggest li a em{
    font-style: italic;
    color:#999;
    font-size:0.8em;
}

JS部分:

1var xhr = null;
 2$('#keyword').bind('input propertychange', function () {
 3    if (xhr) {
 4        xhr.abort();//如果存在ajax的请求,就放弃请求,更多视频教程微信搜索:【码农编程进阶笔记】
 5    }
 6    var inputText = $.trim(this.value);
 7    if (inputText != "") { //检测键盘输入的内容是否为空,为空就不发出请求
 8        xhr = $.ajax({
 9            type: 'POST',
10            url: '/search/suggest',
11            cache: false,//不从浏览器缓存中加载请求信息
12            // data: "keyword=" + inputText,
13            data: {keyword: inputText},
14            dataType: 'json',
15            success: function (json) {
16                //console.log(json);
17                if (json.count != 0) {
18                    //检测返回的结果是否为空
19                    var lists = "";
20                    $.each(json.data, function (index, obj) {
21                        //处理高亮关键词
22                        var searchContent = obj.product_name;
23                        var suggestItem = '';
24                        if (searchContent.toLowerCase().indexOf(inputText.toLowerCase()) > -1) {
25                            var searchRegExp = new RegExp('(' + inputText + ')', "gi");
26                            suggestItem = searchContent.replace(searchRegExp, ("<strong>$1</strong>"));
27                        }
28                        suggestItem = suggestItem + "<em> - " + obj.product_type + "</em>";
29                        //遍历出每一条返回的数据
30                        lists += "<li class='listName' ><a href='http://t.zoukankan.com/search/suggest?id=" + obj.id + "&key=" + encodeURI(searchContent + ' - ' + obj.product_type) + "'>" + suggestItem + "</a></li>";
31                    });
32                    $("#header_search_suggest").html(lists).show();//将搜索到的结果展示出来
33                } else {
34                    $("#header_search_suggest").hide();
35                }
36                //记录搜索历史记录
37                $.post('/search/savesearchlog',{keyword: inputText,count: json.count});
38            }
39        });
40    } else {
41        $("#header_search_suggest").hide();//没有查询结果就隐藏搜索框
42    }
43}).blur(function () {
44    setTimeout('$("#header_search_suggest").hide()',500);//输入框失去焦点的时候就隐藏搜索框,为了防止隐藏过快无法点击,设置延迟0.5秒隐藏
45});
演示效果

如图:

b3400ee8a00edba79e6af214608c5553.gif

最后

你的点赞关注是对我最大的支持,求一键三连:分享朋友圈、点赞、在看

公众号后台回复666,可以获得免费电子书籍

931b74509e2a83317784a94553f65bf0.png

免责声明:文章转载自《使用ElasticSearch服务从MySQL同步数据实现搜索即时提示与全文搜索功能》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ASP.NET中使用HttpWebRequest调用WCFJAVA基础学习_命名规范和注释下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

ansible 的用法

ansible 常用模块 1 command 模块 默认模块,不指定 -m 参数时,使用的就是 command 模块; 但 "<", ">", "|", and "&" 操作都不可以,当然,也不支持管道; 缺点:不支持管道,没法批量执行命令; 示例: ansible 192.168.2.20 -m command -a 'ifconfi...

【转载】java连接MYSQL

原文出自 http://qq163230530.blog.163.com/blog/static/4289250620081186262719/ 这篇文章主要以MySQL为例讲下Java如何连接到数据库的。            当然,首先要安装有JDK(一般是JDK1.5.X)。然后安装MySQL,这些都比较简单,具体过程就不说了。配置好这两个环境后,...

MySQL 4.1/5.0/5.1/5.5各版本的主要区别

1、4.1 增加了子查询的支持,字符集增加UTF-8,GROUP BY语句增加了ROLLUP,mysql.user表采用了更好的加密算法。 2、5.0 增加了Stored procedures、Views、Cursors、Triggers、XA transactions的支持,增加了INFORATION_SCHEMA系统数据库。 3、5.1 增加了Even...

win10安装mysql5.7.29教程以及错误处理

重新配了一台电脑,装了win10系统,安装mysql是出现了一些问题以及解决的方法。记录于此,避免下次安装遇到重复问题。 首先下载mysql5.7.29安装包,本次使用的是zip。已保存在百度网盘 链接:https://pan.baidu.com/s/1y8aahxloQEJTGXqmd95xsg 提取码:e3c6 也可以自己去官网下载: 下载地址:  h...

使用 Sonar 检测代码质量

经历了一段时间的加班赶项目进度之后,今天终于闲下来了。忽然不知道干啥。于是,想着做点什么吧。突然想起了码云上面有个代码分析的功能,用的是 Sonar 于是想来玩玩这个。 一、下载Sonar,和初始化,启动 打开浏览器,搜索sonarqube,进入官网,找到download按钮,下载安装包。浏览器下载慢的话, 可以复制下载链接 到迅雷里边下载。 下载之后,解...

印刷文字识别-身份证识别(阿里云)

以下是自己根据阿里云api文档说明封装的工具类,主要是获取阿里云Oss身份证图片信息 阿里云api文档URL:https://market.aliyun.com/products/57124001/cmapi010401.html?spm=a2c4g.11186623.2.7.VojbRu <?php namespace Helper; use...