Elasticsearch学习记录(1.安装,简单的查询,聚合,防止数据重复,冲突控制等)

Stella981
• 阅读 570

首先我的学习是基于该教程进行的(下列部分代码文字出自该教程,在学习过程中增加我自己的理解和补充,便于更好的裂解和学习,并指出下列教程错误的地方):

http://es.xiaoleilu.com/

安装步骤

  1. java的jdk安装
  2. java的环境变量包括JAVA_HOME,classpath,path的配置
  3. elasticsearch官网下载elasticsearch,并安装配置
  4. 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中的版本。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这