首先我的学习是基于该教程进行的(下列部分代码文字出自该教程,在学习过程中增加我自己的理解和补充,便于更好的裂解和学习,并指出下列教程错误的地方):
安装步骤
- java的jdk安装
- java的环境变量包括JAVA_HOME,classpath,path的配置
- elasticsearch官网下载elasticsearch,并安装配置
- cmd启动elasticsearch
ES安装
安装Elasticsearch唯一的要求是安装官方新版的Java,地址:www.java.com
从 elasticsearch.org/download 下载最新版本的Elasticsearch。
下载完成后。解压缩在安装目录。
在cmd命令行进入安装目录,再进入 bin目录,运行elasticsearch.bat 命令:
启动成功后。在浏览器中输入:http://localhost:9200/ 能看到json语句就ok
!!!!如果运行 elasticsearch.bat时说java_home没set
添加环境变量,若没有就新建
JAVA_HOME=C:\Program Files\Java\jdk1.7.0_55;
path=%JAVA_HOME%\bin;
classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tool.jar;
插件elasticsearch-head安装
cmd bin 目录 :plugin -install mobz/elasticsearch-head
如果不行,就https://github.com/mobz/elasticsearch-head 下载安装包。
在elasticsearch目录下 plugins文件夹下新建head文件夹,解压把文件夹下内容复制到head下。
在浏览器中输入:http://localhost:9200/_plugin/head/查看结果。
以上步骤的安装和配置过程百度同样可以搜索到答案。
文件目录布局
新创建的目录中有以下结构:
- bin:运行Elasticsearch实例和插件管理所需的脚本
- config: 配置文件所在的目录
- lib: Elasticsearch使用的库
Elasticsearch启动后,会创建如下目录(如果目录不存在):
- data: Elasticsearch使用的所有数据的存储位置
- logs: 关于事件和错误记录的文件
- plugins: 存储所安装插件的地方
- work: Elasticsearch使用的临时文件
配置Elasticsearch
配置目录位于config目录下,有两个文件:elasticsearch.yml和loggin.yml。
elasticsearch.yml:负责设置服务器的默认配置值,部分配置值可以在运行时更改,也可作为集群状态的一部分被保留。有2个值不能更改:cluster.name,node.name。 cluster.name属性保存集群的名字,不同的集群用名字来区分,配置成相同集群名字的各个节点形成一个集群。 node.name是实例(该节点)得名字,可以不定义此参数,这是es自动选择一个唯一的名称。
logging.yml定义了多少信息写入系统日志,定义了日志文件,并定期创建新的文件,只有在调整监控,备份方案或系统调试时,才需要修改。
配置上的一些问题:
1.建立索引时,尤其是很多分片和副本的情况下,ES将创建很多文件。所以,系统不能限制打开的文件描述符小于32 000个。在Linux上,一般在/etc/security/limits.conf中修改,当前的值可以用ulimit命令来查看。如果达到极限,Elasticsearch将无法创建新的文件,所以合并会失败,索引会失败,新的索引无法创建。
2.下一组设定关联到单个Elasticsearch实例的Java虚拟机(JVM)的堆内存限制。对小型部署来说,默认的内存限制(1024 M)就足够了,但对于大型项目不够。如果你在日志文件中发现OutOfMemoryError异常的条目,把ES_HEAP_SIZE变量设置到大于1024。当选择分配给JVM的合适内存大小时,记住,通常不应该分配超过50%的系统总内存。
核心类型
- string:字符串;
- number:数字;
- date:日期;
- boolean:布尔型;
- binary:二进制。
插入数据
为每个员工的文档(document)建立索引,每个文档包含了相应员工的所有信息。
每个文档的类型为employee。
employee类型归属于索引megacorp。
megacorp索引存储在Elasticsearch集群中。
实际上这些都是很容易的(尽管看起来有许多步骤)。我们能通过一个命令执行完成的操作:
PUT /megacorp/employee/1
(firefox的restclient中,选择类型为PUT,然后如果是本地,就是http://localhost:9200/megacorp/employee/1)
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
查询数据
单独的一个:http://localhost:9200/megacorp/employee/1
所有的:http://localhost:9200/megacorp/employee/_search
条件查询:
1.查询last_name中包含'Smith'的人 GET /megacorp/employee/_search?q=last_name:Smith 2.dsl查询 选择POST而不是GET!!!!!!! url:http://localhost:9200/megacorp/employee/_search
body:
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
全文查询:
about
//下面的rock和climbing是分开的,也是说我们所查询的是包含rock或者包含climbing单词的所有数据,并不是交集。当然查询的结果会根据相关性进行排序,优先显示交集的部分。
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
短语搜索:
match_phrase
//这样以后相当于查询的是一句话,也就是说交集。
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
高亮显示:
highlight
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
},
"highlight": {
"fields" : {
"about" : {}
}
}
}
分析-聚合(sql-groupby)
聚合(aggregations)
1.让我们找到所有职员中最大的共同点(兴趣爱好)是什么:
{
"aggs": {
"all_interests": {
"terms": { "field": "interests" }
}
}
}
2.如果我们想知道所有姓"Smith"的人最大的共同点(兴趣爱好),我们只需要增加合适的语句既可
{
"query": {
"match": {
"last_name": "smith"
}
},
"aggs": {
"all_interests": {
"terms": {
"field": "interests"
}
}
}
}
3.让我们统计每种兴趣下职员的平均年龄
{
"aggs" : {
"all_interests" : {
"terms" : { "field" : "interests" },
"aggs" : {
"avg_age" : {
"avg" : { "field" : "age" }
}
}
}
}
}
文档元数据
节点 说明
_index 文档存储的地方,这个名字必须是全部小写,不能以下划线开头,不能包含逗号。
_type 文档代表的对象的类,可以是大写或小写,不能包含下划线或逗号。
_id 文档的唯一标识,仅仅是一个字符串,它与_index和_type组合时,就可以在Elasticsearch中唯一标识一个文档。当创建一个文档,你可以自定义_id,也可以让Elasticsearch帮你自动生成。自动生成的ID有22个字符长,URL-safe, Base64-encoded string universally unique identifiers, 或者叫 UUIDs。(自动生成只需要不加ID,然后PUT需要改为POST)
查询一条数据的某几个字段(123这个id的title和text)
http://localhost:9200//website/blog/123?_source=title,text
你只想得到_source字段而不要其他的元数据,你可以这样请求:
GET /website/blog/123/_source
防止插入数据重复的方法:
然而,如果想使用自定义的_id,我们必须告诉Elasticsearch应该在_index、_type、_id三者都不同时才接受请求。为了做到这点有两种方法,它们其实做的是同一件事情。你可以选择适合自己的方式: 1
第一种方法使用op_type查询参数:
PUT /website/blog/123?op_type=create
第二种:
PUT /website/blog/123/_create
处理冲突
(在修改提交的过程中可能有人同时提交了修改,这时为了防止冲突我们需要有一定的处理方法):
我们利用_version的这一优点确保数据不会因为修改冲突而丢失。我们可以指定文档的version来做想要的更改。如果那个版本号不是现在的,我们的请求就失败了。
另一种方法是:
使用外部版本控制系统
可以在Elasticsearch的查询字符串后面添加version_type=external来使用这些版本号。版本号必须是整数,大于零小于9.2e+18——Java中的正的long。
外部版本号与之前说的内部版本号在处理的时候有些不同。它不再检查_version是否与请求中指定的一致,而是检查是否小于指定的版本。如果请求成功,外部版本号就会被存储到_version中。
外部版本号不仅在索引和删除请求中指定,也可以在创建(create)新文档中指定。
例如,创建一个包含外部版本号5的新博客,我们可以这样做:
PUT /website/blog/2?version=5&version_type=external
{
"title": "My first external blog entry",
"text": "Starting to get the hang of this..."
}
在响应中,我们能看到当前的_version号码是5:
{
"_index": "website",
"_type": "blog",
"_id": "2",
"_version": 5,
"created": true
}
现在我们更新这个文档,指定一个新version号码为10:
PUT /website/blog/2?version=10&version_type=external
{
"title": "My first external blog entry",
"text": "This is a piece of cake..."
}
请求成功的设置了当前_version为10:
{
"_index": "website",
"_type": "blog",
"_id": "2",
"_version": 10,
"created": false
}
如果你重新运行这个请求,就会返回一个像之前一样的冲突错误,因为指定的外部版本号不大于当前在Elasticsearch中的版本。