安装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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值