CRUD(Create, Retrieve, Update, Delete)是数据库系统的四种基本操作,分别表示创建、查询、更改、删除,俗称“增删改查”。Elasticsearch作为NoSQL数据库(虽然ES是为搜索引擎而生的,但我更愿意将其看作带有强大文本搜索功能的NoSQL)。

以下示例基于Elasticsearch 2.4版本。

Create

在默认情况下,ES的REST接口的端口号为9200,对接Java client的端口号为9300。

Create操作为向index中索引文档,若index不存在则ES会自动创建;

$ curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{<json data>}'

Java API("org.elasticsearch" % "elasticsearch" % "2.4.1")通过TransportClient与ES集群连接,CRUD操作便是基于此而实现的。

final Settings settings = Settings.settingsBuilder()
.put("client.transport.sniff", true)
.put("client.transport.ping_timeout", 20, TimeUnit.SECONDS)
.put("client", true)
.put("data", false)
.put("cluster.name", "<cluster name>")
.build(); Client client = TransportClient.builder()
.settings(settings).build()
.addTransportAddresses(
new InetSocketTransportAddress(InetAddress.getByName("host1"), 9300),
new InetSocketTransportAddress(InetAddress.getByName("host2"), 9300));

Index Java API创建index或索引document:

import org.elasticsearch.action.index.IndexResponse;

IndexResponse response = client.prepareIndex("twitter", "tweet")
.setSource(documentJson)
.get();

Retrieve

ES的查询DSL大致可以分为两种:

  • Query DSL,主要配合bool、match等使用,相当于SQL中的where子句;
  • Aggregations,相当于SQL中的group by部分,细分为如下三类
  1. Bucketing,聚合函数只能是count(*),表示的是doc命中数,可以嵌套子aggs;
  2. Metric,相比于Bucketing其非常灵活,可配合avgmaxsum等聚合函数,但是不能嵌套子aggs;
  3. Pipeline,以其他aggs的结果作为输入,而不是直接在文档集合上进行操作。

ES的Query DSL功能实在是强大,在本文短短的篇幅中很难阐述完全,故只列举了两个简单实例。在以前的项目中,我使用过1.7版本ES,后来发现2.0.0-beta1版本及之后DSL语法发生很大的变化,比如filteredandor等被废弃掉了,而被bool取而代之;对应的Java API支持链式操作,与Java 8配合写起来非常舒服。

REST通过_search接口进行DSL查询:

$ curl -XGET 'localhost:9200/<index>/_search?pretty' -d'{<dsl>}'

实战List<List<String>> idsList作为过滤条件,其中内一层为and关系、内二层为or关系;然后多字段(为bucketSizeMap的key)aggs,Java 8实现:

BoolQueryBuilder mustQueryBuilder = boolQuery();
if (!(idsList.size() == 1 && idsList.get(0).isEmpty())) {
mustQueryBuilder = idsList.stream().reduce(
boolQuery(),
(mustQB, ids) -> {
BoolQueryBuilder shouldQB = ids.stream().reduce(boolQuery(),
(qb, id) -> qb.should(termQuery(SearchSystem.getEsType(id, idMap), id)),
BoolQueryBuilder::should);
return mustQB.must(shouldQB);
},
BoolQueryBuilder::must);
}
SearchRequestBuilder searchRequestBuilder = client.prepareSearch(indexName)
.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
.setQuery(mustQueryBuilder); for (Map.Entry<String, Integer> entry : bucketSizeMap.entrySet()) {
AggregationBuilder aggregationBuilder = AggregationBuilders
.terms(entry.getKey())
.field(entry.getKey()).size(entry.getValue());
searchRequestBuilder.addAggregation(aggregationBuilder);
}
SearchResponse response = searchRequestBuilder.execute().actionGet();

Bucket Aggregations支持filter aggs,即满足过滤条件后做aggs,

aggs:
<aggs_name>:
filter:
aggs:

其与filter query + aggs在功能上是等价的,

query:
bool:
filter:
aggs:

但是,经测试发现filter query + aggs是比filter aggs查询要快。

Update

update为document级别的操作,即仅支持对某个具体document进行更新;REST通过_update接口:

$ curl -XPOST 'localhost:9200/<_index>/<_type>/<_id>/_update' -d '{<data>}'

Java API则有两种实现方式:UpdateRequest + updateprepareUpdate

// case 1
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index("index");
updateRequest.type("type");
updateRequest.id("1");
updateRequest.doc(jsonBuilder()
.startObject()
.field("gender", "male")
.endObject());
client.update(updateRequest).get(); // case 2
client.prepareUpdate("ttl", "doc", "1")
.setDoc(jsonBuilder()
.startObject()
.field("gender", "male")
.endObject())
.get();

Delete

delete操作通常都伴随着检查index是否存在(exist),exist的RESTful接口与Java API分别如下:

$ curl -XHEAD -i 'http://localhost:9200/twitter'
client.admin().indices()
.prepareExists(indexName)
.execute().actionGet().isExists();

ES提供了三种粗细粒度的删除操作:

  • 删除整个index;
  • 删除index中某一type;
  • 删除特定的document.

RESTful接口:

-- delete complete index
$ curl -XDELETE 'http://localhost:9200/<indexname>'
-- delete a type in index
$ curl -XDELETE 'http://localhost:9200/<indexname>/<typename>'
-- delete a particular document
$ curl -XDELETE 'http://localhost:9200/<indexname>/<typename>/<documentId>

Java API实现:

// delete complete index
client.admin().indices().delete(new DeleteIndexRequest("<indexname>")).actionGet(); // delete a type in index
client.prepareDelete().setIndex("<indexname>").setType("<typename>").setId("*").execute().actionGet(); // delete a particular document
client.prepareDelete().setIndex("<indexname>").setType("<typename>").setId("<documentId>").execute().actionGet(); // or
DeleteResponse response = client.prepareDelete("twitter", "tweet", "1")
.execute()
.actionGet();

Elasticsearch的CRUD:REST与Java API的更多相关文章

  1. Elasticsearch 5.4.3实战--Java API调用:索引mapping创建

    因为项目开发使用的是Java语言, 项目的开发架构是Spring MVC+ maven的jar包管理,  所以今天重点说说ES 5.4.3 的Java API的源码实战 1. pom.xml文件增加依 ...

  2. elasticsearch(一):JAVA api操作

    1.创建一个mavan项目,项目的以来配置如下. <?xml version="1.0" encoding="UTF-8"?> <projec ...

  3. Elasticsearch 5.4.3实战--Java API调用:搜索建议

    通常的搜索引擎,都会根据用户的输入,实时给予匹配的提示. 那么这个功能在elasticsearch中如何实现呢? Elasticsearch里设计了4种类别的Suggester,分别是: Term S ...

  4. Elasticsearch 5.4.3实战--Java API调用:搜索

    ES有多种查询方式,我自己的业务是需要对多个字段进行查询,具体实现类代码如下. package com.cs99lzzs.elasticsearch.service.imp; import java. ...

  5. Elasticsearch 5.4.3实战--Java API调用:批量写入数据

    这个其实比较简单,直接上代码. 注意部分逻辑可以换成你自己的逻辑 package com.cs99lzzs.elasticsearch.service.imp; import java.sql.Tim ...

  6. ElasticSearch入门-增删改查(java api)

    1.增加Index PutMappingRequest mapping = Requests.putMappingRequest(indices).type(mappingType).source(g ...

  7. [搜索]ElasticSearch Java Api(一) -添加数据创建索引

    转载:http://blog.csdn.net/napoay/article/details/51707023 ElasticSearch JAVA API官网文档:https://www.elast ...

  8. Elasticsearch 2.3.3 JAVA api说明文档

    原文地址:https://www.blog-china.cn/template\documentHtml\1484101683485.html 翻译作者:@青山常在人不老 加入翻译:cdcnsuper ...

  9. 第08章 ElasticSearch Java API

    本章内容 使用客户端对象(client object)连接到本地或远程ElasticSearch集群. 逐条或批量索引文档. 更新文档内容. 使用各种ElasticSearch支持的查询方式. 处理E ...

随机推荐

  1. 【组织级项目管理】P2 MSP P3O

    组织级项目管理--有你,有我,有大家 在过去的2年,无论对于企业来讲,还是对于我们个人都有很多大脑的冲击,有几个词大家应该特别耳熟能详:转型,变革,敏捷,互联网+,组织的项目化管理等.就是这些让我们的 ...

  2. 转:聊聊mavenCenter和JCenter

    Gradle支持从maven中央仓库和JCenter上获取构件,那这两者有什么区别呢? maven中央仓库(http://repo1.maven.org/maven2/)是由Sonatype公司提供的 ...

  3. redis 学习笔记(1)

    redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...

  4. 【Machine Learning】决策树案例:基于python的商品购买能力预测系统

    决策树在商品购买能力预测案例中的算法实现 作者:白宁超 2016年12月24日22:05:42 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本 ...

  5. Servlet监听器笔记总结

    监听器Listener的概念 监听器的概念很好理解,顾名思义,就是监视目标动作或状态的变化,目标一旦状态发生变化或者有动作,则立马做出反应. Servlet中的也有实现监听器的机制,就是Listene ...

  6. ZKWeb网页框架1.4正式发布

    本次更新的内容有 添加更快的批量操作函数 添加IDatabaseContext.FastBatchSave 添加IDatabaseContext.FastBatchDelete 注意这些函数不会触发注 ...

  7. 【热门技术】EventBus 3.0,让事件订阅更简单,从此告别组件消息传递烦恼~

    一.写在前面 还在为时间接收而烦恼吗?还在为各种组件间的消息传递烦恼吗?EventBus 3.0,专注于android的发布.订阅事件总线,让各组件间的消息传递更简单!完美替代Intent,Handl ...

  8. eclipse如何添加Memory Analyzer

    ①启动Eclipse,并打开"Install New software..."对话框: ②点击Add,如图: ③点击OK,最后一直点next,完成

  9. SharePoint 2016 入门视频教程

    之前一直有朋友让自己录一些SharePoint的入门视频,之前没有太多时间,一个巧合的机会收到CSDN学院的邮件,可以在CSDN上发布视频教程,自己就录了一些.说起录视频也是蛮辛苦的,每天下班吃完饭要 ...

  10. [转]ThinkPHP中实例化对象M()和D()的区别,select和find的区别

    1.ThinkPHP中实例化对象M()和D()的区别 在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会 ...