安装Elasticsearch 全文搜索/大数据分析
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。Elasticsearch的应用场景一个线上商城系统,用户需要搜索商...
ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
Elasticsearch的应用场景
- 一个线上商城系统,用户需要搜索商城上的商品。在这里你可以用es存储所有的商品信息和库存信息,用户只需要输入”空调”就可以搜索到他需要搜索到的商品。
- 一个运行的系统需要收集日志,用这些日志来分析、挖掘从而获取系统业务未来的趋势。你可以用logstash(ELK中的一个产品,elasticsearch/logstash/kibana)收集、转换你的日志,并将他们存储到es中。一旦数据到达es中,就你可以在里面搜索、运行聚合函数等操作来挖掘任何你感兴趣的信息。
- 如果你有想基于大量数据(数百万甚至数十亿的数据)快速调查、分析并且要将分析结果可视化的需求。你可以用es来存储你的数据,用kibana构建自定义的可视化图形、报表,为业务决策提供科学的数据依据。
安装ElasticSearch
版本说明:ES5 需要 Java 8 及以上的版本。ES7 开始内置了 Java 环境
首先确认下jdk有没有安装
java -version
下载源文件,解压,重新建一个用户,将目录的所属组修改为此用户,因为 elasticsearch 无法用 root 用户启动。
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.0.tar.gz
tar zxvf elasticsearch-6.3.0.tar.gz
useradd elasticsearch
passwd elasticsearch
chown -R elasticsearch:elasticsearch elasticsearch-6.3.0
cd elasticsearch-6.3.0
./bin/elasticsearch // 启动
./bin/elasticsearch -d //后台启动
cd config
vim jvm.options
# 修改参数如下(服务器小,不配大容量)
-Xms256m
-Xmx256m
可能存在问题
Exception in thread "main" java.nio.file.AccessDeniedException: /usr/local/src/elasticsearch-6.3.0/config/jvm.options
at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)
at java.nio.file.Files.newInputStream(Files.java:152)
at org.elasticsearch.tools.launchers.JvmOptionsParser.main(JvmOptionsParser.java:58)
报这个错是因为用户的权限不足,因此在配置和启动ElasticSearch节点的时候要注意给用户赋予对应的权限
chown -R myuser:myuser /usr/local/src/elasticsearch-6.3.0
连接Elasticsearch:
1、Elasticsearch开启之后,可以直接通过http://127.0.0.1:9200/查看基本信息。
{
"name": "iEX7av1",
"cluster_name": "elasticsearch",
"cluster_uuid": "8TMqWFwnTLiBlRKtU7a8YQ",
"version": {
"number": "6.3.0",
"build_flavor": "default",
"build_type": "tar",
"build_hash": "424e937",
"build_date": "2018-06-11T23:38:03.357887Z",
"build_snapshot": false,
"lucene_version": "7.3.1",
"minimum_wire_compatibility_version": "5.6.0",
"minimum_index_compatibility_version": "5.0.0"
},
"tagline": "You Know, for Search"
}
安装中文分词 elasticsearch-analysis-ik
ik有两种分词模式,ik_max_word,和ik_smart模式
- ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;
- ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。
索引时,为了提供索引的覆盖范围,通常会采用ik_max_word分析器,会以最细粒度分词索引,搜索时为了提高搜索准确度,会采用ik_smart分析器,会以粗粒度分词。使用ik_max_word会占用更多的存储空间
#在线安装
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.0/elasticsearch-analysis-ik-6.3.0.zip
#本地安装
./bin/elasticsearch-plugin install file:///usr/local/src/elasticsearch-analysis-ik-6.3.0.zip
安装好后 重启es会看到 加载了 ik分词了
安装完毕后,发现在ES的安装目录下的plugins目录下多了一个analysis-ik目录(内容是ik的zip包解压后根目录下的所有文件,一共是5个jar文件和1个properties配置文件),另外ES的安装目录下的config目录下多了一个analysis-ik目录(内容是ik的zip包解压后根目录下的config目录下所有文件,用于放置ik的自定义词库)
安装Kibana
Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。安装Kibana要装与ES相同的版本
wget https://artifacts.elastic.co/downloads/kibana/kibana-6.3.0-linux-x86_64.tar.gz
tar -zxvf kibana-6.3.0-linux-x86_64.tar.gz
cd kibana-6.3.0-linux-x86_64
#启动Kibana
./bin/kibana
http://localhost:5601访问web页面;
使用POSTMAN工具发送PUT请求创建
ES的基本用法:ES以RESTFul风格来命名API的, 其API的基本格式如下
http://<ip>:<port>/<索引>/<类型>/<文档id>
ES的动作是以http方法来决定的: 常用的http方法: GET/PUT/POST/DELETE
es支持多字段结构,例如:我们将常用的搜索条件和排序字段(销量,时间)配置到mappings.properties中
{
"settings":{
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings":{
"man":{
"properties":{
"word_count":{
"type": "integer"
},
"author":{
"type": "keyword"
},
"title":{
"type": "text"
},
"publish_date":{
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || epoch_millis"
}
}
}
}
}
如下图
观察返回结果已经成功。
插入文档:PUT 127.0.0.1:9200/people/man
{
"name": "chenjie",
"country": "China",
"age": 30,
"date": "1994-09-27"
}
修改文档:POST 127.0.0.1:9200/people/man/1/_update
{
"doc":{
"name":"chenjie_update"
}
}
删除文档
DELETE 127.0.0.1:9200/people/man/1
批量操作
批量操作 bulk
- 支持在一次 API 调用中,对不同的索引进行操作
- 支持四种类型操作Index/Create/Update/Delete
- 可以在 URI 中指定 Index,也可以在请求的 Payload 中进行
- 单条操作失败,并不会影响其他操作
- 返回结果包括了每一条操作执行的结果
测试命令:
POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test2", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
使用PHPAPi构建和查询
创建表和测试数据,索引相当于MySQL中的表,文档相当于 MySQL 中的行记录。程序在新增/修改/删除记录的时候调用ES的接口对ES文档进行同步的新增/修改/删除操作。同步构建有很大缺陷。比如:ES宕机或者ES处理文档消耗了很长的时间影响用户的体验。可以使用KaFka中间件来进行异步构建文档。
在 composer.json 文件中引入 elasticsearch-php
{
"require": {
"elasticsearch/elasticsearch": "~6.0"
}
}
CREATE TABLE articles ( id INT NOT NULL PRIMARY KEY auto_increment, title VARCHAR ( 200 ) NOT NULL COMMENT '标题', content text COMMENT '内容' );
INSERT INTO articles ( title, content )
VALUES
( 'Laravel 测试1', 'Laravel 测试文章内容1' ),
( 'Laravel 测试2', 'Laravel 测试文章内容2' ),
( 'Laravel 测试3', 'Laravel 测试文章内容3' );
实例化
require './vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->build();
elasticsearch的动态性质,在添加第一个文档的时候自动创建了索引和一些默认设置。
创建索引
$params['index'] = 'articles_index';
$params['body']['settings']['number_of_shards'] = 2;
$params['body']['settings']['number_of_replicas'] = 0;
$client->indices()->create($params);
将文档加入索引
foreach ($lists as $row) {
$params = [
'body' =>
[
'id' => $row['id'],
'title' => $row['title'],
'content' => $row['content']
],
'id' => 'article_' . $row['id'], //maping db id
'index' => 'articles_index',
'type' => 'articles_type'
];
$client->index($params);
}
从索引中获取文档
$params = ['index' => 'articles_index', 'type' => 'articles_type', 'id' => 'articles_1'];
$res = $client->get($params);
print_r($res);
删除索引
$params = [
'index' => 'articles_index'
];
$res = $client->indices()->delete($params);
print_r($res);
搜索文档,如果需要获取更多明细信息可以根据mysql表ID获取
<?php
$params = ['index' => 'articles_index', 'type' => 'articles_type'];
$params['body']['query']['match']['content'] = 'Laravel';
$params['body']['size'] = 10;
$params['body']['from'] = 200;
$params['body']['sort'] = ['content' => ['order' => 'desc']];
$res = $client->search($params);
print_r($res);
//相当于sql语句:select * from articles where content='Laravel' limit 200,10 order by content desc;
从索引中删除文档
$params = ['index' => 'articles_index', 'type' => 'articles_type', 'id' => 'articles_1'];
$res = $client->delete($params);
print_r($res);
Elasticsearch更新和删除文档的过程。
- 删除和更新也都是写操作,但是Elasticsearch中的文档是不可变的,因此不能被删除或者改动以展示其变更;
- 磁盘上的每个段都有一个相应的.del文件。当删除请求发送后,文档并没有真的被删除,而是在.del文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del文件中被标记为删除的文档将不会被写入新段。
- 在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
ElasticSearch搜索term和terms的区别
在查询的字段只有一个值的时候,应该使用term而不是terms,在查询字段包含多个的时候才使用terms(类似于sql中的in、or),使用terms语法,JSON中必须包含数组。
第一种(单个值,term):
{
"query":{
"bool":{
"must":[
{
"range":{
"update_time":{
"gt":"1488556800000"
}
}
},
{
"term":{
"lang":1
}
},
{
"terms":{
"domain":[
"dailymasala.co",
"goldenmob.com"
]
}
},
{
"prefix":{
"user_id":"errVideo_setInterval_"
}
}
]
}
},
"from":0,
"size":10
}
第二种(数组形式,terms):
{
"query": {
"bool": {
"must": [
{
"range": {
"update_time": {
"gt": "1488556800000"
}
}
},
{
"terms": {
"lang": [1]
}
},
{
"terms": {
"domain": [
"dailymasala.co",
"goldenmob.com"
]
}
},
{
"prefix": {
"user_id": "errVideo_setInterval_"
}
}
]
}
},
"from": 0,
"size": 10
}
elasticsearch 中term与match区别
term是代表完全匹配,也就是精确查询,搜索前不会再对搜索词进行分词,所以我们的搜索词必须是文档分词集合中的一个。比如说我们要找标题为北京奥运的所有文档
match查询会先对搜索词进行分词,分词完毕后再逐个对分词结果进行匹配,因此相比于term的精确搜索,match是分词匹配搜索。要搜索词的分词集合中的一个或多个存在于文档中即可,例如,当我们搜索中国杭州
,搜索词会先分词为中国
和杭州
,只要文档中包含搜索
和杭州
任意一个词,都会被搜索到。对于match搜索,可以按照分词后的分词集合的or或者and进行匹配,默认为or
curl -XGET http://localhost:9200/index/doc/_search?pretty -d
'{
"query": {
"match": {
"content": {
"query": "中国世界",
"operator": "and"
}
}
}
}'
ES性能优化
{
"settings":{
"number_of_shards": 3,
"number_of_replicas": 1,
"index.store.type": "niofs",
"index.query.default_field": "content",
"index.unassigned.node_left.delayed_timeout": "5m",
},
"mappings":{
"man":{
"dynamic":true,
"_all":{"enabled":false},
"properties":{
}
}
}
}
安全控制可以使用apache/nginx的http认证
在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh 。 默认情况下每个分片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是 近 实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见.
更新延迟问题:搜索时加上?refresh=wait_for,表示如果1秒内有请求立即更新并可见。
更多推荐
所有评论(0)