目录
这个不用看,看DSL语言哪个就行
这里多个文档是指,批量操作多个文档
批量获取文档数据是通过_mget的API来实现的
在URL中不指定index和type
GET _mget
{
"docs":
[
{
"_index": "es_db",
"_type": "_doc",
"_id": 1
},
{
"_index": "es_db",
"_type": "_doc",
"_id": 2
}
]
}
响应结果如下:
{
"docs" : [
{
"_index" : "es_db",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"_seq_no" : 7,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "张三666",
"sex" : 1,
"age" : 25,
"address" : "广州天河公园",
"remark" : "java developer"
}
},
{
"_index" : "es_db",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "李四",
"sex" : 1,
"age" : 28,
"address" : "广州荔湾大厦",
"remark" : "java assistant"
}
}
]
}
在URL中指定index
GET / es_db / _mget
{
"docs": [
{
"_type": "_doc",
"_id": 3
},
{
"_type": "_doc",
"_id": 4
}
]
}
在URL中指定index和type
GET / es_db / _doc / _mget
{
"docs": [
{
"_id": 1
},
{
"_id": 2
}
]
}
批量对文档进行写操作是通过_bulk的API来实现的
参数类似于:
{"actionName":{"_index":"indexName", "_type":"typeName","_id":"id"}}
{"field1":"value1", "field2":"value2"}
批量创建文档create
POST _bulk {
"create": {
"_index": "article",
"_type": "_doc",
"_id": 3
}
} {
"id": 3,
"title": "白起老师1",
"content": "白起老师666",
"tags": ["java", "面向对象"],
"create_time": 1554015482530
} {
"create": {
"_index": "article",
"_type": "_doc",
"_id": 4
}
} {
"id": 4,
"title": "白起老师2",
"content": "白起老师NB",
"tags": ["java", "面向对象"],
"create_time": 1554015482530
}
普通创建或全量替换index
POST _bulk {
"index": {
"_index": "article",
"_type": "_doc",
"_id": 3
}
} {
"id": 3,
"title": "图灵徐庶老师(一)",
"content": "图灵学院徐庶老师666",
"tags": ["java", "面向对象"],
"create_time": 1554015482530
} {
"index": {
"_index": "article",
"_type": "_doc",
"_id": 4
}
} {
"id": 4,
"title": "图灵诸葛老师(二)",
"content": "图灵学院诸葛老师NB",
"tags": ["java", "面向对象"],
"create_time": 1554015482530
}
批量删除delete
POST _bulk {
"delete": {
"_index": "article",
"_type": "_doc",
"_id": 3
}
} {
"delete": {
"_index": "article",
"_type": "_doc",
"_id": 4
}
}
批量修改update
POST _bulk {
"update": {
"_index": "article",
"_type": "_doc",
"_id": 3
}
} {
"doc": {
"title": "ES大法必修内功"
}
} {
"update": {
"_index": "article",
"_type": "_doc",
"_id": 4
}
} {
"doc": {
"create_time": 1554018421008
}
}
Domain Specific Language:领域专用语言
Elasticsearch provides a ful1 Query DSL based on JSON to define queries
Elasticsearch提供了基于JSON的DSL来定义查询。
DSL由叶子查询子句和复合查询子句两种子句组成。

无查询条件是查询所有,默认是查询所有的,或者使用match_all表示所有
GET / es_db / _doc / _search
{
"query": {
"match_all": {}
}
}
模糊匹配主要是针对文本类型的字段,文本类型的字段会对内容进行分词,对查询时,也会对搜索条件进行分词,然后通过倒排索引查找到匹配的数据,模糊匹配主要通过match等参数来实现
match条件还支持以下参数:
组合条件查询是将叶子条件查询语句进行组合而形成的一个完整的查询条件
must/filter/shoud/must_not 等的子条件是通过 term/terms/range/ids/exists/match 等叶子条件为参数的
注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当是多个条件时,对应的是一个数组

在查询上下文中,查询会回答这个问题——“这个文档匹不匹配这个查询,它的相关度高么?”
如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个_score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂的,因此也需要一定的时间。
在过滤器上下文中,查询会回答这个问题——“这个文档匹不匹配?”
答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。
过滤上下文 是在使用filter参数时候的执行环境,比如在bool查询中使用must_not或者filter
另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提高很多性能。
根据名称精确查询姓名 term, term查询不会对字段进行分词查询,会采用精确匹配
注意: 采用term精确查询, 查询字段映射类型属于为keyword.
举例:
POST / es_db / _doc / _search
{
"query": {
"term": {
"name": "admin"
}
}
}
根据备注信息模糊查询 match, match会根据该字段的分词器,进行分词查询
举例:
POST / es_db / _doc / _search
{
"from": 0,
"size": 2,
"query": {
"match": {
"address": "广州"
}
}
}
多字段模糊匹配查询与精准查询 multi_match
POST / es_db / _doc / _search
{
"query": {
"multi_match": {
"query": "张三",
"fields": ["address", "name"]
}
}
}
POST / es_db / _doc / _search
{
"query": {
"query_string": {
"query": "广州 OR 长沙"
}
}
}
POST / es_db / _doc / _search
{
"query": {
"query_string": {
"query": "admin OR 长沙",
"fields": ["name", "address"]
}
}
}
注:json请求字符串中部分字段的含义
range:范围关键字
POST / es_db / _doc / _search
{
"query": {
"range": {
"age": {
"gte": 25,
"lte": 28
}
}
}
}
POST / es_db / _doc / _search
{
"query": {
"range": {
"age": {
"gte": 25,
"lte": 28
}
}
},
"from": 0,
"size": 2,
"_source": ["name", "age", "book"], // 显示哪几个字段
"sort": {
"age": "desc" // 排序字段
}
}
Filter过滤器方式查询,它的查询不会计算相关性分值,也不会对结果进行排序, 因此效率会高一点,查询的结果可以被缓存。
POST / es_db / _doc / _search
{
"query": {
"bool": {
"filter": {
"term": {
"age": 25
}
}
}
}
}
match:模糊匹配,需要指定字段名,但是输入会进行分词,比如"hello world"会进行拆分为hello和world,然后匹配,如果字段中包含hello或者world,或者都包含的结果都会被查询出来,也就是说match是一个部分匹配的模糊查询。查询条件相对来说比较宽松。
term: 这种查询和match在有些时候是等价的,比如我们查询单个的词hello,那么会和match查询结果一样,但是如果查询"hello world",结果就相差很大,因为这个输入不会进行分词,就是说查询的时候,是查询字段分词结果中是否有"hello world"的字样,而不是查询字段中包含"hello world"的字样。当保存数据"hello world"时,elasticsearch会对字段内容进行分词,"hello world"会被分成hello和world,不存在"hello world",因此这里的查询结果会为空。这也是term查询和match的区别。
match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that world不满足,world hello也不满足条件。
query_string:和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛
ES中映射可以分为动态映射和静态映射
在关系数据库中,需要事先创建数据库,然后在该数据库下创建数据表,并创建表字段、类型、长度、主键等,最后才能基于表插入数据。而Elasticsearch中不需要定义Mapping映射(即关系型数据库的表、字段等),在文档写入Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射。
动态映射规则如下:

删除原创建的索引:DELETE /es_db
创建索引:PUT /es_db
创建文档(ES根据数据类型, 会自动创建映射)
PUT / es_db / _doc / 1
{
"name": "Jack",
"sex": 1,
"age": 25,
"book": "java入门至精通",
"address": "广州小蛮腰"
}
获取文档映射:GET /es_db/_mapping
静态映射是在Elasticsearch中也可以事先定义好映射,包含文档的各字段类型、分词器等,这种方式称之为静态映射
设置文档映射
PUT / es_db {
"mappings": {
"properties": {
"name": {
"type": "keyword",
"index": true,
"store": true
},
"sex": {
"type": "integer",
"index": true,
"store": true
},
"age": {
"type": "integer",
"index": true,
"store": true
},
"book": {
"type": "text",
"index": true,
"store": true
},
"address": {
"type": "text",
"index": true,
"store": true
}
}
}
}
字符串:string,string类型包含 text 和 keyword。
text:该类型被用来索引长文本,在创建索引前会将这些文本进行分词,转化为词的组合,建立索引;允许es来检索这些词,text类型不能用来排序和聚合。
keyword:该类型不能分词,可以被用来检索过滤、排序和聚合,keyword类型不可用text进行分词模糊检索。
数值型:long、integer、short、byte、double、float
日期型:date
布尔型:boolean
将 book 字段设置为 keyword 映射 (只能精准查询, 不能分词查询,能聚合、排序)
将 book 字段设置为 text 映射能模糊查询, 能分词查询,不能聚合、排序
POST / es_db / _doc / _search
{
"query": {
"term": {
"book": "elasticSearch入门至精通"
}
}
}
PUT / es_db
{
"mappings": {
"properties": {
"name": {
"type": "keyword",
"index": true,
"store": true
},
"sex": {
"type": "integer",
"index": true,
"store": true
},
"age": {
"type": "integer",
"index": true,
"store": true
},
"book": {
"type": "text",
"index": true,
"store": true,
"analyzer": "ik_smart",
"search_analyzer": "ik_smart"
},
"address": {
"type": "text",
"index": true,
"store": true
}
}
}
}
POST / es_db / _doc / _search
{
"query": {
"match": {
"address": "广"
}
}
}
POST / es_db / _doc / _search {
"query": {
"match": {
"address": "广州"
}
}
}
具体方法
1)如果要推倒现有的映射, 你得重新建立一个静态索引
2)然后把之前索引里的数据导入到新的索引里
3)删除原创建的索引
4)为新索引起个别名, 为原索引名
POST _reindex // 命令
{
"source": {
"index": "db_index" // 来源数据
},
"dest": {
"index": "db_index_2" //目标数据
}
}
DELETE /db_index // 删除原来的索引
PUT /db_index_2 /_alias /db_index // 对新建的索引重新命名
注意: 通过这几个步骤就实现了索引的平滑过渡,并且是零停机
在数据库领域中,有两种方法来确保并发更新,不会丢失数据:
这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。
Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据、或者将相关情况报告给用户。
再以创建一个文档为例 ES老版本
PUT /db_index /_doc /1
{
"name": "Jack",
"sex": 1,
"age": 25,
"book": "Spring Boot 入门到精通",
"remark": "hello world"
}
实现_version乐观锁更新文档,根据版本去查询
PUT /db_index /_doc /1?version=1
{
"name": "Jack",
"sex": 1,
"age": 25,
"book": "Spring Boot 入门到精通",
"remark": "hello world"
}
ES新版本(7.x)不使用version进行并发版本控制 if_seq_no=版本值&if_primary_term=文档位置
POST /es_sc/_search
DELETE /es_sc
POST /es_sc/_doc/1
{
"id": 1,
"name": "图灵学院",
"desc": "图灵学院白起老师",
"create_date": "2021-02-24"
}
POST /es_sc/_update/1
{
"doc": {
"name": "图灵教育666"
}
}
// 下面这两个有一个能执行成功,一个执行不成功,因为seq_no版本号变了
POST /es_sc/_update/1/?if_seq_no=1&if_primary_term=1
{
"doc": {
"name": "图灵学院1"
}
}
POST /es_sc/_update/1/?if_seq_no=1&if_primary_term=1
{
"doc": {
"name": "图灵学院2"
}
}
node1.baiqi.cn 服务器使用baiqi用户来修改配置文件
mkdir -p /usr/local/es/elasticsearch-7.6.1/log
mkdir -p /usr/local/es/elasticsearch-7.6.1/data
cd /usr/local/es/elasticsearch-7.6.1/config
rm -rf elasticsearch.yml
vim elasticsearch.yml
cluster.name: baiqi-es
node.name: node1.baiqi.cn
path.data: /usr/local/es/elasticsearch-7.6.1/data
path.logs: /usr/local/es/elasticsearch-7.6.1/log
network.host: node1.baiqi.cn
http.port: 9200
discovery.seed_hosts: ["IP1", "IP2", "IP3"]
cluster.initial_master_nodes: ["节点1名称", "节点2名称", "节点3名称"]
bootstrap.system_call_filter: false
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"
修改jvm.option配置文件,调整jvm堆内存大小
node1.baiqi.cn使用baiqi用户执行以下命令调整jvm堆内存大小,每个人根据自己服务器的内存大小来进行调整。
cd /usr/local/es/elasticsearch-7.6.1/config
vim jvm.options
-Xms2g
-Xmx2g
node2.baiqi.cn与node3.baiqi.cn也需要修改es配置文件
node2.baiqi.cn使用baiqi用户执行以下命令修改es配置文件
mkdir -p /usr/local/es/elasticsearch-7.6.1/log
mkdir -p /usr/local/es/elasticsearch-7.6.1/data
cd /usr/local/es/elasticsearch-7.6.1/config
vim elasticsearch.yml
cluster.name: baiqi-es
node.name: node2.baiqi.cn
path.data: /usr/local/es/elasticsearch-7.6.1/data
path.logs: /usr/local/es/elasticsearch-7.6.1/log
network.host: node2.baiqi.cn
http.port: 9200
discovery.seed_hosts: ["IP1", "IP2", "IP3"]
cluster.initial_master_nodes: ["节点1名称", "节点2名称", "节点3名称"]
bootstrap.system_call_filter: false
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"
node3.baiqi.cn使用baiqi用户执行以下命令修改配置文件
mkdir -p /usr/local/es/elasticsearch-7.6.1/log
mkdir -p /usr/local/es/elasticsearch-7.6.1/data
cd /usr/local/es/elasticsearch-7.6.1/config
vim elasticsearch.yml
cluster.name: baiqi-es
node.name: node3.baiqi.cn
path.data: /usr/local/es/elasticsearch-7.6.1/data
path.logs: /usr/local/es/elasticsearch-7.6.1/log
network.host: node3.baiqi.cn
http.port: 9200
discovery.seed_hosts: ["IP1", "IP2", "IP3"]
cluster.initial_master_nodes: ["节点1名称", "节点2名称", "节点3名称"]
bootstrap.system_call_filter: false
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"
查看集群状态:
GET _cat/nodes?v
GET _cat/health?v 有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|
不知何故,我似乎无法获得包含我的聚合的响应...使用curl它按预期工作:HBZUMB01$curl-XPOST"http://localhost:9200/contents/_search"-d'{"size":0,"aggs":{"sport_count":{"value_count":{"field":"dwid"}}}}'我收到回复:{"took":4,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":90,"max_score":0.0,"hits":[]},"a
1.回顾.TransportServicepublicclassTransportServiceextendsAbstractLifecycleComponentTransportService:方法:1publicfinalTextendsTransportResponse>voidsendRequest(finalTransport.Connectionconnection,finalStringaction,finalTransportRequestrequest,finalTransportRequestOptionsoptions,TransportResponseHandlerT>
我有一个Rails应用程序,现在设置了ElasticSearch和Tiregem以在模型上进行搜索,我想知道我应该如何设置我的应用程序以对模型中的某些索引进行模糊字符串匹配。我将我的模型设置为索引标题、描述等内容,但我想对其中一些进行模糊字符串匹配,但我不确定在何处进行此操作。如果您想发表评论,我将在下面包含我的代码!谢谢!在Controller中:defsearch@resource=Resource.search(params[:q],:page=>(params[:page]||1),:per_page=>15,load:true)end在模型中:classResource'Us
使用method_missing时在Ruby中,它是almostalwaysagoodidea定义respond_to_missing?respond_to_missing?接受两个参数;我们正在检查的方法的名称(symbol),以及一个指示我们是否应该在检查中包含私有(private)方法的bool值(include_all)。现在我感到困惑的是:method_missing不接受任何可能指示它是否应该调用私有(private)方法的参数,如respond_to_missing?做。此外,method_missing无论原始方法调用是在公共(public)上下文还是私有(privat
我正在对用户的提要进行分页,并想模拟我正在使用的API的响应。API可以返回奇怪的结果,所以我想确保如果API返回我已经看到的项目,请停止分页。我使用minitest在第一次调用方法get_next_page时stub,但我想在第二次和第三次用不同的值调用它时stub。我应该只使用rSpec吗?ruby新手...这是片段test"crawlerdoesnotpaginateifnonewitemsinnextpage"do#1:A,B#2:B,D=>D#3:A=>stopcrawler=CrawlJob.newfirst_page=[{"id"=>"item-A"},{"id"=>"i
我似乎找不到一种优雅的方式来做到这一点......给定一个日期,我如何找到下一个星期二,即日历月的第2个或第4个星期二?例如:给定2012-10-19然后返回2012-10-23或给定2012-10-31然后返回2012-11-13OctoberNovemberSuMoTuWeThFrSaSuMoTuWeThFrSa12345612378910111213456789101415161718192011121314151617212223242526271819202122232428293031252627282930 最佳答案
美团外卖搜索工程团队在Elasticsearch的优化实践中,基于Location-BasedService(LBS)业务场景对Elasticsearch的查询性能进行优化。该优化基于Run-LengthEncoding(RLE)设计了一款高效的倒排索引结构,使检索耗时(TP99)降低了84%。本文从问题分析、技术选型、优化方案等方面进行阐述,并给出最终灰度验证的结论。1.前言最近十年,Elasticsearch已经成为了最受欢迎的开源检索引擎,其作为离线数仓、近线检索、B端检索的经典基建,已沉淀了大量的实践案例及优化总结。然而在高并发、高可用、大数据量的C端场景,目前可参考的资料并不多。因此
开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建
文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就