Elasticsearch【基础入门】
一.操作index
1.查看index
GET /_cat/indices?v
2.增加index
PUT /index名
3.删除index
DELETE /index名
二.操作index
1.新增document
--PUT /index名/type名/id
PUT /movie_index/movie/1
{ "id":1,
"name":"operation red sea",
"doubanScore":8.5,
"actorList":[
{"id":1,"name":"zhang yi"},
{"id":2,"name":"hai qing"},
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/2
{
"id":2,
"name":"operation meigong river",
"doubanScore":8.0,
"actorList":[
{"id":3,"name":"zhang han yu"}
]
}
注意: 如果之前没建过 index 或者 type,es 会自动创建。
2.查询type 全部数据
GET /index名/type名/_search
3.查找指定 id 的 document 数据
GET /index名/type名/id值
4.修改 document
修改分两种: 整体替换和只修改某个字段
整体修改:和新增document差不多
PUT /movie_index/movie/3
{
"id":"3",
"name":"incident red sea",
"doubanScore":"8.0",
"actorList":[
{"id":"1","name":"zhang chen"}
]
}
只修改某个字段 :使用post方法
POST /movie_index/movie/3/_update
{
"doc": {
--字段值 : 更新后的值
"doubanScore":"8.1"
}
}
5.删除一个 document
DELETE /movie_index/movie/3
6.条件查询
原始数据格式
{ "id":1,
"name":"operation red sea",
"doubanScore":8.5,
"actorList":[
{"id":1,"name":"zhang yi"},
{"id":2,"name":"hai qing"},
{"id":3,"name":"zhang han yu"}
]
}
查询全部
GET /movie_index/movie/_search
{
"query": {
"match_all": {}
}
}
------等价于
GET /movie_index/movie/_search
按照指定字段值查询
GET /movie_index/movie/_search
{
"query": {
"match": {
"name": "sea" --字段值
}
}
}
按照字段子属性查询
GET /movie_index/movie/_search
{
"query": {
"match": {
"actorList.name": "zhang" --json数组取子元素字段
}
}
}
7.按照短语整体查询
按照短语查询的意思是指, 匹配某个 field 的整个内容, 不再利用分词技术
GET /movie_index/movie/_search
{
"query": {
"match_phrase": {
"name": "operation red"
}
}
}
说明: 把operation red作为一个整体来看待
对比一下
--包含 operation 或者 red 的都会被查找出来
GET /movie_index/movie/_search
{
"query": {
"match": {
"name": "operation red"
}
}
}
8.模糊查询
校正匹配分词,当一个单词都无法准确匹配,es 通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。
GET /movie_index/movie/_search
{
"query": {
"fuzzy": {
"name": "red"
}
}
}
9.查询后过滤
GET /movie_index/movie/_search
{
"query": {
"match": {
"name": "red"
}
},
"post_filter": {
"term": {
"actorList.id": "3"
}
}
}
10.查询前过滤(推荐)
--条件:actorList.id=3 or actorList.id= 1 && name contains "zhang"
GET movie_index/movie/_search
{
"query": {
"bool": {
"filter": [
{"term":
{"actorList.id": 3}
},
{
"term":
{"actorList.id": 1}
}
],
"must":
{"match": {
"name": "zhang"
}}
}
}
}
must、should、must_not区别
must可以理解为 &,should理解为 |, must_not理解为!【与、或、非的关系】
must+should的使用可以理解为:先按照must过滤,过滤出来的结果的score分数增加。should只是辅助作用
must
年龄39 且 性别'女'
GET /bank/_search
{
"query": {
"bool": {
"must": [
{"match": {
"age": "39"
}},
{"match": {
"gender": "F"
}}
]
}
}
}
should
年龄39 或 性别'女'
GET /bank/_search
{
"query": {
"bool": {
"should": [
{"match": {
"age": "39"
}},
{"match": {
"gender": "F"
}}
]
}
}
}
must_not
年龄不是39 且 性别不为 '女'
GET /bank/_search
{
"query": {
"bool": {
"must_not": [
{"match": {
"age": "39"
}},
{"match": {
"age": "40"
}}
]
}
}
}
must+should
结果和must结果一样,不同就是“must+should”的结果的score增加。
GET /bank/_search
{
"query": {
"bool": {
"must": [
{"match": {
"age": "39"
}}
],
"should": [
{"match": {
"gender": "F"
}}
]
}
}
}
11.按照范围过滤
lt:小于,lte:小于等于,gt:大于,gte:大于等于
GET movie_index/movie/_search
{
"query": {
"bool": {
"filter": {
"range": {
"doubanScore": {
"gt": 5,
"lt": 9
}
}
}
}
}
}
12.排序
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red operation"}
}
, "sort": [
{
"doubanScore": { --指定排序字段
"order": "desc" --指定排序规则
}
}
]
}
13.分页查询
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"from": 10, --从第几条开始查询
"size": 10 --展示几条
}
14.聚合
select count(*) from group by gender
GET /bank/_search
{
"aggs": {
"groupby_gender": {
"terms": {
"field": "gender.keyword",
"size": 1
}
}
}
}
多组聚合
相对于Sql中的两个group by语句的查询结果
selec sum(balance), max(balance) from .. group by gender
selec sum(balance) from .. group by age
GET /bank/_search
{
"query": {
"match": {
"address": "Terrace"
}
},
"aggs": {
--按照gender聚合
"groupby_gender": {
"terms": {
"field": "gender.keyword",
"size": 2
},
"aggs": {
"b_sum": {
"sum": {
"field": "balance"
}
},
"b_max":{
"max": {
"field": "balance"
}
}
}
},
----按照age聚合
"groupby_age": {
"terms": {
"field": "age",
"size": 100
},
"aggs": {
"b_sum": {
"sum": {
"field": "balance"
}
}
}
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"_source": ["balance", "age"]
}
三. Scala API插入数据到ES
使用java API同样可以实现
1.ES中新建测试Index
GET /user/_search --查询
--向Index插入一条数据,同时创建Index
PUT /user/_doc/1
{
"name":"zhangsan",
"age":10
}
2.User样例类
case class User(name:String,age:Int)
3.ES工具类
import io.searchbox.client.{JestClient, JestClientFactory}
import io.searchbox.client.config.HttpClientConfig
import io.searchbox.core.{Bulk, Index}
/**
* @description: ES工具类
* @author: HaoWu
* @create: 2020年09月09日
*/
object ESUtil {
// 构建JestClientFactory
//ES服务器地址 注意:可以设置1个也可以设置1个Collection,要转为java的集合
import scala.collection.JavaConverters._
val esServerUrl = Set("http://hadoop102:9200", "http://hadoop103:9200", "http://hadoop104:9200").asJava
//构建客户端工厂
private val factory = new JestClientFactory
var conf: HttpClientConfig = new HttpClientConfig.Builder(esServerUrl)
.multiThreaded(true)
.maxTotalConnection(100)
.connTimeout(10 * 1000)
.readTimeout(10 * 1000)
.build()
factory.setHttpClientConfig(conf)
/**
* 获取ES客户端
*/
def getESClient(): JestClient = {
factory.getObject
}
/**
* 插入单条数据
*
* @param index :插入的Index
* @param source :满足两种类型参数:1.source 2.(id,source) ,其中source可以是样例类对象 或 json对象字符串
*/
def insertSingle(index: String, source: Any): Unit = {
val client: JestClient = getESClient()
val action =
source match {
case (id, s: Any) => {
new Index.Builder(s)
.index(index)
.`type`("_doc")
.id(id.toString) //ES中的id为String类型,当入参的id为int类型可能插入错误。
.build()
}
case (_) => {
new Index.Builder(source)
.index(index)
.`type`("_doc")
.build()
}
}
client.execute(action)
client.close()
}
/**
* 批量插入数据
*
* @param index :插入的Index
* @param sources :满足两种类型参数:1.source 2.(id,source) ,其中source可以是样例类对象 或 Json对象字符串
* 说明:将来数据使用mapPartition批量写入,所以参数封装为Iterator类型
*/
def insertBluk(index: String, sources: Iterator[Object]) {
// 1.获取ES客户端
val client: JestClient = getESClient()
// 2.构建Builder
val builder: Bulk.Builder = new Bulk.Builder()
.defaultIndex(index)
.defaultType("_doc")
// 3.为Builder添加action
//================== 方式一 ========================================
/* sources.foreach(
source => {
val action =
source match {
case (id: String, s) => { //入参是一个元祖(id, source)
new Index.Builder(s)
.id(id)
.build()
}
case (_) => { //入参是source,样例类,或者 json对象字符串
new Index.Builder(source)
.build()
}
}
//添加action
builder.addAction(action)
}
)*/
//================== 方式二 ========================================
sources.map { //转换为action
case (id: String, s) => {
new Index.Builder(s)
.id(id)
.build()
}
case (source) => {
new Index.Builder(source)
.build()
}
} //往builder添加action
.foreach(builder.addAction)
// 4.执行插入
client.execute(builder.build())
// 5.关闭客户端
client.close()
}
4.测试
插入单条数据
val source1 = User("lisi", 20) //id随机生成
val source2 = ("11",User("lisi", 20)) //id为10
insertSingle("user", source1)
insertSingle("user", source2)
查询结果
{
"_index": "user",
"_type": "_doc",
"_id": "pwvTcXQBrKDUC6YPHEQZ",
"_score": 1,
"_source": {
"name": "lisi",
"age": 20
}
},
{
"_index": "user",
"_type": "_doc",
"_id": "11",
"_score": 1,
"_source": {
"name": "lisi",
"age": 20
}
}
批量插入数据
//不指定id 和 指定id
val sources = Iterator(User("wangwu", 21), (99,User("zhaoliu", 30)))
insertBluk("user",sources)
查询结果
{
"_index": "user",
"_type": "_doc",
"_id": "qwvgcXQBrKDUC6YPbETl",
"_score": 1,
"_source": {
"name": "wangwu",
"age": 21
}
},
{
"_index": "user",
"_type": "_doc",
"_id": "rAvgcXQBrKDUC6YPbETl",
"_score": 1,
"_source": {
"_1": 99,
"_2": {
"name": "zhaoliu",
"age": 30
}
}
}
四.JavaAPI 条件查询ES 解析
需求:根据日期(date)和关键字(sku_name)过滤,并且分别对年龄(age)和性别(gender)分组,根据当前页数(startPage),每页展示条数(pageSize)
DSL查询
GET /gmall0421_sale_detail/_search
{
"query": {
"bool": {
"filter": {
"term": {
"dt": "2020-09-12" //日期date
}
},
"must": [
{"match": {
"sku_name": {
"query": "手机小米", //关键字keyword
"operator": "and"
}
}}
]
}
},
"aggs": {
"group_by_gender": {
"terms": {
"field": "user_gender", //按性别分组(gender)
"size": 10
}
},
"group_by_age": {
"terms": {
"field": "user_age", //按年龄分组(age)
"size": 150
}
}
},
"from": 0, //查询的页数(startPage)
"size": 1000 //每页记录数(pageSize)
}
ESUtil
scala代码,写DSL语句更美观
package com.bigdata.real_time_project.gmallpublisher.uitl
import io.searchbox.client.config.HttpClientConfig
import io.searchbox.client.{JestClient, JestClientFactory}
import io.searchbox.core.{Bulk, Index, Search, SearchResult}
import scala.collection.JavaConverters._
/**
* @description: ES工具类
* @author: HaoWu
* @create: 2020年09月09日
*/
object ESUtil {
// 构建JestClientFactory
//ES服务器地址
val esServerUrl = Set("http://hadoop102:9200", "http://hadoop103:9200", "http://hadoop104:9200")
.asJava //要转为java的集合
private val factory = new JestClientFactory
var conf: HttpClientConfig = new HttpClientConfig.Builder(esServerUrl)
.multiThreaded(true)
.maxTotalConnection(100)
.connTimeout(10 * 1000)
.readTimeout(10 * 1000)
.build()
factory.setHttpClientConfig(conf)
/**
* 获取ES客户端
*/
def getESClient(): JestClient = {
factory.getObject
}
//获取DSL语句
def getQueryDSL(date: String, keyword: String, startPage: Int, pageSize: Int) = {
val dsl =
s"""
|{
| "query": {
| "bool": {
| "filter": {
| "term": {
| "dt": "${date}"
| }
| },
| "must": [
| {"match": {
| "sku_name": {
| "query": "${keyword}",
| "operator": "and"
| }
| }}
| ]
| }
| },
|
| "aggs": {
| "group_by_gender": {
| "terms": {
| "field": "user_gender",
| "size": 10
| }
| },
| "group_by_age": {
| "terms": {
| "field": "user_age",
| "size": 150
| }
| }
|
| },
|
|
| "from": ${startPage},
| "size": ${pageSize}
|}
|""".stripMargin
dsl
}
}
查询并解析
Java代码解析
//前端访问:http://localhost:8070/sale_detail?date=2019-05-20&&keyword=手机小米&&startpage=1&&size=5
public Map<String, Object> getSailDetailAndAggs(String date, String keyword, int startpage, int size) throws IOException {
//1.查询 es
JestClient client = ESUtil.getESClient();
Search.Builder builder = new Search.Builder(ESUtil.getQueryDSL(date, keyword, startpage, size))
.addIndex("gmall0421_sale_detail")
.addType("_doc");
SearchResult searchResult = client.execute(builder.build());
client.close();
//2.解析查询结果
HashedMap result = new HashedMap();
//2.1 total
result.put("total", searchResult.getTotal());
//2.2 details
ArrayList<Map> details = new ArrayList<>();
List<SearchResult.Hit<Map, Void>> hits = searchResult.getHits(Map.class);
for (SearchResult.Hit<Map, Void> hit : hits) {
Map source = hit.source;
details.add(source);
}
result.put("detail", details);
//2.3 gender聚合结果
Map<String, Object> genderMap = new HashMap<>();
List<TermsAggregation.Entry> bucketsGender = searchResult.getAggregations()
.getTermsAggregation("group_by_gender")
.getBuckets();
for (TermsAggregation.Entry bucket : bucketsGender) {
genderMap.put(bucket.getKey(), bucket.getCount());
}
result.put("genderAgg",genderMap);
//2.3 age聚合结果
Map<String, Object> ageMap = new HashMap<>();
List<TermsAggregation.Entry> bucketsAge = searchResult.getAggregations()
.getTermsAggregation("group_by_age")
.getBuckets();
for (TermsAggregation.Entry bucket : bucketsAge) {
ageMap.put(bucket.getKey(), bucket.getCount());
}
result.put("ageAgg",ageMap);
return result;
}
Elasticsearch【基础入门】的更多相关文章
- Elasticsearch 基础入门
原文地址:Elasticsearch 基础入门 博客地址:http://www.extlight.com 一.什么是 ElasticSearch ElasticSearch是一个基于 Lucene 的 ...
- ElasticSearch基础入门学习笔记
前言 本笔记的内容主要是在从0开始学习ElasticSearch中,按照官方文档以及自己的一些测试的过程. 安装 由于是初学者,按照官方文档安装即可.前面ELK入门使用主要就是讲述了安装过程,这里不再 ...
- ElasticSearch基础入门
1.query查询表达式 Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 查询表达式(Query DSL)是一种非常灵活又富有表现力的 查询语言,它支持构建更加复杂和健壮的 ...
- Elasticsearch基础入门,详情可见官方文档
索引文档: 对于员工目录,我们将做如下操作: 每个员工索引一个文档,文档包含该员工的所有信息. 每个文档都将是 employee 类型 . 该类型位于 索引 megacorp 内. 该索引保存在我们的 ...
- ElasticSearch 基础入门 and 操作索引 and 操作文档
基本概念 索引: 类似于MySQL的表.索引的结构为全文搜索作准备,不存储原始的数据. 索引可以做分布式.每一个索引有一个或者多个分片 shard.每一个分片可以有多个副本 replica. 文档: ...
- ELKStack的基础入门和中文指南
一.ELKStack的中文指南 redhat系列配置repo源 rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch vi / ...
- Logstash 基础入门
原文地址:Logstash 基础入门博客地址:http://www.extlight.com 一.前言 Logstash 是一个开源的数据收集引擎,它具有备实时数据传输能力.它可以统一过滤来自不同源的 ...
- Kibana 基础入门
原文地址:Kibana 基础入门 博客地址:http://www.extlight.com 一.前言 Kibana 是一个开源的分析和可视化平台,旨在与 Elasticsearch 合作.Kibana ...
- Elasticsearch 7.x 之文档、索引和 REST API 【基础入门篇】
前几天写过一篇<Elasticsearch 7.x 最详细安装及配置>,今天继续最新版基础入门内容.这一篇简单总结了 Elasticsearch 7.x 之文档.索引和 REST API. ...
- [转]小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
原文地址:https://www.cnblogs.com/wangjunwei/p/11392825.html 第1节零基础快速入门SpringBoot2.0 小D课堂 - 零基础入门SpringBo ...
随机推荐
- fd定时器--timerfd学习
定时器 可以用系统定时器信号SIGALARM 最近工作需要于是又发现了一个新玩意timerfd配合epoll使用. man 手册看一下 TIMERFD_CREATE(2) Linux Programm ...
- Git 极速上手(超简单)
前言:本文主要介绍了一种快速入门使用Git的方法,通过四步完成本地仓库构建和推送到远程仓库(Github.Gitee码云),简单说明最常用的命令,不需要明白Git的原理即可使用,本文不介绍具体原理. ...
- exec系统调用 && 进程的加载过程
exec系统调用会从指定的文件中读取并加载指令,并替代当前调用进程的指令.从某种程度上来说,这样相当于丢弃了调用进程的内存,并开始执行新加载的指令. exec系统调用会保留当前的文件描述符表单.所以任 ...
- 13.G1垃圾收集器
G1收集器是一款面向服务器的垃圾收集器,也是HotSpot在JVM上力推的垃圾收集器,并赋予取代CMS的使命.为什么对G1收集器给予如此高的期望呢?既然对G1收集器寄予了如此高的期望,那么他一定是有其 ...
- Linux&C———进程间通信
管道和有名管道 消息队列 共享内存 信号 套接字 由于进程之间的并不会像线程那样共享地址空间和数据空间,所以进程之间就必须有自己特有的通信方式,这篇博客主要介绍自己了解到的几种进程之间的通信方式,内容 ...
- Webshell 一句话木马
Webshell介绍 什么是 WebShell webshell就是以asp.php.jsp或者cgj等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门 由于 webshell其大多是 ...
- MAC安装vue.js
一.下载node node下载地址:https://nodejs.org/en/download/ 下载后点击安装即可. node -v 检查安装是否成功 二.安装 淘宝镜像 (npm) npm in ...
- spring笔记-MultiValueMap
即一个键对应多个值,Spring的内部实现是LinkedMultiValueMap MultiValueMap接口 一键多值的使用场景是比较多的,在使用该数据结构之前,通常会自己定义 Map<K ...
- 面向政务企业的开发者工具集-逐浪文本大师v0.1正式发布(含代码全部开源啦!)
这是一款基于.net 4.7环境开发的开发者工具. 一个实用的windows小工具集合,里面包含了多个常用的小软件.其中的批量修改文件名及文件内容功能,可以自定义修改规则,支持规则的导入与导出.不需要 ...
- 【linux系统】命令学习(七)进阶命令 curl jq
curl 支持dict file ftp ftps gopher http https imap 1.实现代理 curl -x 129.3.3.3:8888 https://baidu.com 2.g ...