elasticSearch-api
这里是kibana上操作的(也可以用postman操作):
1.环境准备
elasticsearch 6.6.0
2.数据准备
//----------------------数据准备----------------------//
//创建文档(index,type,docId)
//索引可以不存在(会自动创建)
PUT /movie_index/movie/1
{
"id":100,
"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":200,
"name":"operation meigong river",
"doubanScore":8.0,
"actorList":[
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/3
{
"id":300,
"name":"incident red sea",
"doubanScore":5.0,
"actorList":[
{"id":4,"name":"zhang san feng"}
]
}
2.全局操作
//----------------------全局操作----------------------//
//健康状态
GET /_cat/health?v
//查看所有节点
GET /_cat/nodes?v
//查看所有索引
GET /_cat/indices?v
//查看所有别名
GET /_cat/aliases?v
//查看所有模板
GET /_cat/templates?v
//查看索引分片情况
GET /_cat/shards/movie_index?v
//强制合并片(物理删除文档)
POST /_forcemerge
4.针对索引操作
//----------------------索引操作----------------------//
//创建索引
PUT /movie_index
//删除索引
DELETE /movie_index
//手动定义 mapping
PUT movie_chn_1
{
"mappings": {
"movie": {
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "text",
"analyzer": "ik_smart"
},
"doubanScore": {
"type": "double"
},
"actorList": {
"properties": {
"id": {
"type": "long"
},
"name": {
"type": "keyword"
}
}
}
}
}
}
}
//索引数据拷贝
POST /_reindex
{
"source": {
"index": "movie_chn_1"
},
"dest": {
"index": "movie_chn_2"
}
}
//----------------------索引别名(用起来和索引一样用)----------------------//
//创建 Index 的时候声明
PUT 索引名
{
"aliases": {
"索引别名": {}
}
}
//为已存在的索引增加别名
POST _aliases
{
"actions": [
{
"add": {
"index": "索引名",
"alias": "索引别名"
}
}
]
}
//删除某个索引的别名
POST _aliases
{
"actions": [
{
"remove": {
"index": "索引名",
"alias": "索引别名"
}
}
]
}
//----------------------索引模板----------------------//
//使用场景: 分割索引
PUT _template/template_movie2020
{
//模式匹配: 只要是movie_test开头的index都用这个模板
"index_patterns": [
"movie_test*"
],
//分片1
"settings": {
"number_of_shards": 1
},
//别名: 这里有两个
//第一个: 每个index独有的, index + -query
//第二个: 所有使用这个模板创建index共有的,相当于分在了同一个组,单使用这个别名查询时,那么所有对应的index的数据都会被查询到
"aliases": {
"{index}-query": {},
"movie_test-query": {}
},
//映射(数据结构)
"mappings": {
//Type(默认类型)
"_doc": {
"properties": {
"id": {
"type": "keyword"
},
"movie_name": {
"type": "text",
"analyzer": "ik_smart"
}
}
}
}
}
//查看某个模板的详情
GET /_template/template_movie0523
5.针对doc操作(增删改)
代码如下(示例):
//----------------------增删改----------------------//
//根据文档的id删除
//文件删除标记,什么时候物理删除取决于片合并
//删除索引是会立即释放空间的,不存在逻辑删除
DELETE /movie_index/movie/3
//替换文档(put 存在的文档id 幂等性)
PUT /movie_index/movie/3
{
"id":300,
"name":"incident red sea",
"doubanScore":5.0,
"actorList":[
{"id":4,"name":"zhang cuishan"}
]
}
//post进行新增操作,无法保证幂等性
POST /movie_index/movie/
{
"id":300,
"name":"incident red sea",
"doubanScore":5.0,
"actorList":[
{"id":4,"name":"zhang cuishan"}
]
}
//根据文档id更新文档
POST /movie_index/movie/1/_update
{
"doc":{
"name":"新的字段值"
}
}
//根据条件更新文档
POST /movie_index/_update_by_query
{
"query": {
"match":{
"actorList.id":1
}
},
"script": {
"lang": "painless",
"source":"for(int i=0;i<ctx._source.actorList.length;i++){if(ctx._source.actorList[i].id==3){ctx._source.actorList[i].name='tttt'}}"
}
}
//删除文档属性
POST /movie_index/movie/1/_update
{
"script" : "ctx._source.remove('name')"
}
//根据条件删除文档
POST /movie_index /_delete_by_query
{
"query": {
"match_all": {}
}
}
6.针对doc操作(查)
查询1(示例):
//----------------------查询操作(重点)----------------------//
//根据文档id查询
GET /movie_index/movie/3
//查询全部
GET /movie_index/_search
{
"query": {
"match_all": {}
}
}
//按分词查询(必须使用分词 text 类型)
GET /movie_index/_search
{
"query": {
"match": {
"name": "operation red sea"
}
}
}
//按照分词子属性查询
GET /movie_index/_search
{
"query": {
"match": {
"actorList.name": "zhang han yu"
}
}
}
//按照短语查询(相当于 like %短语%)不分词
GET /movie_index/_search
{
"query": {
"match_phrase": {
"actorList.name": "zhang han yu"
}
}
}
//通过 term 精准搜索匹配(必须使用 keyword 类型)
GET /movie_index/_search
{
"query": {
"term": {
"actorList.name.keyword": {
"value": "zhang han yu"
}
}
}
}
//容错匹配
GET /movie_index/_search
{
"query": {
"fuzzy": {
"name": "rad"
}
}
}
//先匹配,在过滤
GET /movie_index/_search
{
"query": {
"match": {
"name": "red"
}
},
"post_filter": {
"term": {
"actorList.id": "3"
}
}
}
//匹配和过滤同时(推荐使用)
GET /movie_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "red"
}
}
],
"filter": {
"term": {
"actorList.id": "3"
}
}
}
}
}
//按照豆瓣评分范围过滤
GET /movie_index/_search
{
"query": {
"range": {
"doubanScore": {
"gte": 6,
"lte": 9
}
}
}
}
//按照豆瓣评分降序排序
GET /movie_index/_search
{
"query": {
"match": {
"name": "red"
}
},
"sort": [
{
"doubanScore": {
"order": "desc"
}
}
]
}
//分页查询
GET /movie_index/_search
{
"from": 0,
"size": 1
}
//查询指定字段
GET /movie_index/_search
{
"_source": ["id","name"]
}
//高亮显示
GET /movie_index/_search
{
"query": {
"match": {
"name": "red"
}
},
"highlight": {
"fields": {
"name": {}
},
"pre_tags": "<h1>",
"post_tags": "</h1>"
}
}
查询2(示例):
#新建索引
PUT test4
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"desc":{
"type": "keyword"
}
}
}
}
#插入数据
PUT test4/_doc/1
{
"name":"张三name",
"desc":"张三desc"
}
PUT test4/_doc/2
{
"name":"张三name2",
"desc":"张三desc2"
}
#分词器查询(并不是查询索引里的数据,而是将text的内容用分词器拆分的结果)
GET _analyze
{
"analyzer": "keyword",
"text": ["张三name"]
}
GET _analyze
{
"analyzer": "standard",
"text": "张三name"
}
GET test4/_search
{
"query": {
"term": {
"name": "张"
}
}
}
#==keyword不会被分词器解析==
GET test4/_search
{
"query": {
"term": {
"desc": "张三desc"
}
}
}
查询3(示例):
PUT test4/_doc/3
{
"t1":"22",
"t2":"2020-4-6"
}
PUT test4/_doc/4
{
"t1":"33",
"t2":"2020-4-7"
}
#精确查询多个值
GET test4/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"t1": "22"
}
},
{
"term": {
"t1": "33"
}
}
]
}
}
}
#highlight:高亮
#pre_tags,post_tags:自定义高亮条件,前缀后缀
GET chen/user/_search
{
"query": {
"match": {
"name": "李四"
}
},
"highlight": {
"pre_tags": "<p class='key' style='color:red'",
"post_tags": "</p>",
"fields": {
"name":{}
}
}
}
7.聚合操作
//----------------------聚合操作----------------------//
//需求1: 取出每个演员共参演了多少部电影
//aggs 聚合
//myAggs 名字,随便取
//terms 分组聚合操作,相当于group by
//size 显示多少条数据
GET /movie_index/_search
{
"aggs": {
"myAggs": {
"terms": {
"field": "actorList.name.keyword",
"size": 10
}
}
}
}
//需求 2:每个演员参演电影的平均分是多少,并按评分排序
GET /movie_index/_search
{
"aggs": {
"groupByName": {
"terms": {
"field": "actorList.name.keyword",
"size": 10,
"order": {
"avg_score": "desc"
}
},
"aggs": {
"avg_score": {
"avg": {
"field": "doubanScore"
}
}
}
}
}
}
8.批处理
//----------------------批处理----------------------//
//批处理(添加两个文档)要求写在一行
POST /movie_index/movie/_bulk
{"index":{"_id":66}}
{"id":300,"name":"incident red sea","doubanScore":5.0,"actorList":[{"id":4,"name":"zhang cuishan"}]}
{"index":{"_id":88}}
{"id":300,"name":"incident red sea","doubanScore":5.0,"actorList":[{"id":4,"name":"zhang cuishan"}]}
// 在一个批量操作中,先更新第一个文档(ID 为 66),再删除第二个文档(ID 为 88)
POST /movie_index/movie/_bulk
{"update":{"_id":"66"}}
{"doc": { "name": "wudangshanshang" } }
{"delete":{"_id":"88"}}
9.分词
//----------------------分词----------------------//
//英文默认分词规则
GET /_analyze
{
"text": "hello world"
}
//中文默认分词规则
GET /_analyze
{
"text": "我是中国人"
}
//使用ik分词器(灵巧的)
GET /_analyze
{
"text": "我是中国人",
"analyzer": "ik_smart"
}
//最大分词
GET /_analyze
{
"text": "我是中国人",
"analyzer": "ik_max_word"
}
10.分词器安装
#安装ik分词器
unzip elasticsearch-analysis-ik-6.6.0.zip -d /opt/module/elasticsearch-6.6.0/plugins/ik
#重启es就可以了,es 会加载插件
#----------------------自定义词库----------------------#
#本地指定:
#1. 进入ik分词器配置文件目录
cd /opt/module/elasticsearch-6.6.0/plugins/ik/config
#2. 创建字典文件
vim myword.txt
#3. 将字典文件配置到ik分词器
vim IKAnalyzer.cfg.xml
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">myword.txt</entry>
#远程指定:
#1. 修改ik分词器配置文件(这里把文件放在Nginx上)
vim IKAnalyzer.cfg.xml
#注意: 需要将本地配置注释掉
<!--用户可以在这里配置远程扩展字典 -->
<entry key="remote_ext_dict">http://hadoop102:80/fenci/myword.txt</entry>
11.java-api
索引操作:
public class ES_Index {
private static final String HOST_NAME = "localhost";
private static final Integer PORT = 9200;
private static RestHighLevelClient client;
//创建ES客户端
static {
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(HOST_NAME, PORT));
client = new RestHighLevelClient(restClientBuilder);
}
//关闭ES客户端
public void close() {
if (null != client) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//创建索引
public void addIndex() throws IOException {
//创建索引
CreateIndexRequest request = new CreateIndexRequest("chen");
CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
//响应状态
System.out.println("索引创建操作: " + response.isAcknowledged());
}
//查询索引
public void selectIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("chen");
GetIndexResponse response = client.indices().get(request, RequestOptions.DEFAULT);
System.out.println("索引查询操作: " +response.getAliases());
System.out.println("索引查询操作: " +response.getMappings());
System.out.println("索引查询操作: " +response.getSettings());
}
//删除索引
public void deleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("chen");
AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println("索引删除操作: "+response.isAcknowledged());
}
public static void main(String[] args) throws IOException {
ES_Index index=new ES_Index();
//index.addIndex();
//index.selectIndex();
index.deleteIndex();
index.close();
}
}
文档操作:
public class ES_Doc {
private static final String HOST_NAME = "localhost";
private static final Integer PORT = 9200;
private static RestHighLevelClient client;
//创建ES客户端
static {
RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(HOST_NAME, PORT));
client = new RestHighLevelClient(restClientBuilder);
}
//关闭ES客户端
public void close() {
if (null != client) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//插入数据
public void addDoc() throws IOException {
IndexRequest request = new IndexRequest();
User user = new User("张三", "男", 18);
//向es插入数据,必须将数据转换为json格式
String userJson = new ObjectMapper().writeValueAsString(user);
request.index("user").id("1001").source(userJson, XContentType.JSON);
IndexResponse response = client.index(request, RequestOptions.DEFAULT);
System.out.println("文档创建操作: " + response.getResult());
}
//修改数据(局部修改)
public void updateDoc() throws IOException {
UpdateRequest request = new UpdateRequest();
request.index("user").id("1001").doc(XContentType.JSON, "sex", "女");
UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
System.out.println("文档修改操作: " + response.getResult());
}
//获取数据
public void getDoc() throws IOException {
GetRequest request = new GetRequest();
request.index("user").id("1001");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
User user = new ObjectMapper().readValue(response.getSourceAsString(), User.class);
System.out.println("文档获取操作: " + user);
}
//删除数据
public void deleteDoc() throws IOException {
DeleteRequest request = new DeleteRequest();
request.index("user").id("1001");
DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
System.out.println("文档删除操作: " + response.getResult());
}
//批量插入数据
public void addBatch() throws IOException {
BulkRequest request = new BulkRequest();
request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON, "name", "张三", "sex", "男", "age", 10));
request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON, "name", "李四", "sex", "男", "age", 20));
request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON, "name", "王五", "sex", "女", "age", 30));
request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON, "name", "赵六", "sex", "男", "age", 40));
request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON, "name", "孙七", "sex", "女", "age", 50));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println("文档批量新增操作: " + response.getTook());
System.out.println("文档批量新增操作: " + !response.hasFailures());//是否失败
}
//批量删除数据
public void deleteBatch() throws IOException {
BulkRequest request = new BulkRequest();
request.add(new DeleteRequest().index("user").id("1001"));
request.add(new DeleteRequest().index("user").id("1002"));
request.add(new DeleteRequest().index("user").id("1003"));
request.add(new DeleteRequest().index("user").id("1004"));
request.add(new DeleteRequest().index("user").id("1005"));
BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
System.out.println("文档批量删除操作: " + response.getTook());
System.out.println("文档批量删除操作: " + !response.hasFailures());//是否失败
}
//查询(重点)
public void searchDoc() throws IOException {
SearchRequest request = new SearchRequest();
request.indices("user");
//1.查询索引中的全部数据
//request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
//2.查询年龄为30的数据
//request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 30)));
//3.分页查询,当前第0页,每页两条
//request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).from(0).size(2));
//4.排序,倒序
//request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).sort("age", SortOrder.DESC));
//5.过滤字段(排除和包含,也可以是数组)
//request.source(new SearchSourceBuilder().fetchSource("name", null));
//6.组合查询
//BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//6.1 must相当于and
//boolQueryBuilder.must(QueryBuilders.matchQuery("age", 30));
//boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "女"));
//6.2 should相当于or
//boolQueryBuilder.should(QueryBuilders.matchQuery("age", 30));
//boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "女"));
//request.source(new SearchSourceBuilder().query(boolQueryBuilder));
//7.范围查询
//request.source(new SearchSourceBuilder().query(QueryBuilders.rangeQuery("age").gte(30).lte(40)));
//8.模糊查询Fuzziness.ONE即只差1个字符
//request.source(new SearchSourceBuilder().query(QueryBuilders.fuzzyQuery("name", "王五").fuzziness(Fuzziness.ONE)));
//9.高亮显示
//SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchPhraseQuery("name", "张三"));
//builder.highlighter(new HighlightBuilder().preTags("<font color='red'>").postTags("</font>").field("name"));
//request.source(builder);
//10.聚合查询
//SearchSourceBuilder builder = new SearchSourceBuilder();
//MaxAggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");
//builder.aggregation(aggregationBuilder);
//request.source(builder);
//11.分组查询
SearchSourceBuilder builder = new SearchSourceBuilder();
TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println("--条数: " + hits.getTotalHits());
System.out.println("--用时: " + response.getTook());
hits.forEach((item)->{
System.out.println("--数据: " + item.getSourceAsString());
});
}
public static void main(String[] args) throws IOException {
ES_Doc doc = new ES_Doc();
//doc.addDoc();
//doc.updateDoc();
//doc.getDoc();
//doc.deleteDoc();
//doc.addBatch();
//doc.deleteBatch();
doc.searchDoc();
doc.close();
}
}
12.spring-data-elasticsearch
实体类
: 关键在于@Document和@Field注解
shards 代表分片
replicas 代表副本
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "product", shards = 3, replicas = 1)
public class Product {
@Id
private Long id;//商品唯一标识
@Field(type = FieldType.Text)
private String title;//商品名称
@Field(type = FieldType.Keyword)
private String category;//分类名称
@Field(type = FieldType.Double)
private Double price;//商品价格
@Field(type = FieldType.Keyword,index = false)
private String images;//图片地址
}
dao层
: 这样就已经可以了,类似mybatis-plus的BaseMapper,封装好了一些操作
@Repository
public interface ProductDao extends ElasticsearchRepository<Product,Long> {
}
yaml
:不用怎么配置,默认就去找localhost:9200
测试
:不知道为啥dao的很多方法都过时了,看源码注释让回去用elasticsearchRestTemplate,感觉更繁琐
@SpringBootTest
class ElasticsearchApplicationTests {
@Autowired
ElasticsearchRestTemplate elasticsearchRestTemplate;
@Autowired
ProductDao productDao;
@Test
void createIndex() {
//创建索引,系统初始化会自动创建索引
System.out.println("创建索引");
}
@Test
void deleteIndex() {
//创建索引,系统初始化会自动创建索引
boolean flg = elasticsearchRestTemplate.deleteIndex(Product.class);
System.out.println("删除索引 = " + flg);
}
//新增数据
@Test
void addDoc() {
Product product = new Product();
product.setId(1001L);
product.setTitle("华为手机");
product.setCategory("手机");
product.setPrice(2999.0);
product.setImages("www.huawei.com");
productDao.save(product);
}
//修改
@Test
void updateDoc() {
Product product = new Product();
product.setId(1001L);
product.setTitle("小米手机");
product.setCategory("手机");
product.setPrice(4999.0);
product.setImages("www.xiaomi.com");
productDao.save(product);
}
//根据 id 查询
@Test
void findById() {
Product product = productDao.findById(1001L).get();
System.out.println(product);
}
//查询所有
@Test
void findAll() {
Iterable<Product> products = productDao.findAll();
for (Product product : products) {
System.out.println(product);
}
}
//删除
@Test
public void delete() {
productDao.deleteById(1001L);
}
//批量新增
@Test
public void saveAll() {
List<Product> productList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Product product = new Product();
product.setId((long) i);
product.setTitle("[" + i + "]小米手机");
product.setCategory("手机");
product.setPrice(1999.0 + i);
product.setImages("http://www.atguigu/xm.jpg");
productList.add(product);
}
productDao.saveAll(productList);
}
//分页查询
@Test
void findByPageable() {
Sort orders = Sort.by(Sort.Direction.DESC, "id");
Pageable pageable = PageRequest.of(0, 5, orders);
Page<Product> products = productDao.findAll(pageable);
products.forEach(System.out::println);
}
/**
* term 查询
* search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
*/
@Test
void termQuery() {
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");
Iterable<Product> products = productDao.search(termQueryBuilder);
products.forEach(System.out::println);
}
/**
* term 查询加分页
*/
@Test
void termQueryByPage() {
PageRequest pageRequest = PageRequest.of(0, 5);
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("category", "手机");
Iterable<Product> products = productDao.search(termQueryBuilder, pageRequest);
products.forEach(System.out::println);
}
}
13.Jest
依赖
<!--Java 操作 ES 的客户端工具 Jest-->
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>5.3.3</version>
</dependency>
<!--Jest 需要的依赖-->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>
<!--Jest 需要的依赖-->
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>commons-compiler</artifactId>
<version>3.0.16</version>
</dependency>
<!-- ElasticSearch 依赖 -->
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.6.0</version>
</dependency>
execute 需要的参数为Action
Action
是一个接口,有很多实现,需要哪一个就构造哪一个
SearchSourceBuilder
用来构造查询条件
object MyEsUtil {
//声明Jest客户端工厂
private var jestFactory: JestClientFactory = _
def build(): Unit = {
jestFactory = new JestClientFactory
jestFactory.setHttpClientConfig(
new HttpClientConfig.Builder(util.Arrays.asList("http://hadoop102:9200", "http://hadoop103:9200", "http://hadoop104:9200"))
.multiThreaded(true)
.maxTotalConnection(20)
.connTimeout(10000)
.readTimeout(1000)
.build()
)
}
//提供获取jest客户端的方法
def getJestClient: JestClient = {
if (jestFactory == null) {
//创建jest客户端工厂对象
build()
}
jestFactory.getObject
}
//向es中插入单条数据 方式1 将插入文档的数据以json的形式直接传递
def putIndex1(): Unit = {
val jestClient: JestClient = getJestClient
//定义执行的source
val source: String =
"""
|{
| "id":100,
| "name":"operation red sea",
| "doubanScore":8.5,
| "actorList":[
| {"id":1,"name":"zhang yi"},
| {"id":2,"name":"hai qing"},
| {"id":3,"name":"zhang han yu"}
| ]
|}
|""".stripMargin
//source表示要插入到索引中的文档,底层会转换成json格式字符串,所以也可以传对象
val index: Index = new Index.Builder(source)
.index("movie_index_5")
.`type`("_doc")
.id("1")
.build()
val result: DocumentResult = jestClient.execute(index)
println(result.getJsonString)
jestClient.close()
}
//向es中插入单条数据 方式1 将插入文档的数据以json的形式直接传递
def putIndex2(): Unit = {
val jestClient: JestClient = getJestClient
//定义执行的source
val source: String =
"""
|{
| "id":100,
| "name":"operation red sea",
| "doubanScore":8.5,
| "actorList":[
| {"id":1,"name":"zhang yi"},
| {"id":2,"name":"hai qing"},
| {"id":3,"name":"zhang han yu"}
| ]
|}
|""".stripMargin
//注意:集合一定得是java的集合
val users: util.List[User] = util.Arrays.asList(
User(3, "zhangsan"),
User(4, "lisi"),
User(5, "wangwu")
)
val movie: Movie = Movie(101, "葫芦娃", 7.9F, users)
//source表示要插入到索引中的文档,底层会转换成json格式字符串,所以也可以传对象
val index: Index = new Index.Builder(movie)
.index("movie_index_5")
.`type`("_doc")
.id("2")
.build()
val result: DocumentResult = jestClient.execute(index)
println(result.getJsonString)
jestClient.close()
}
def main(args: Array[String]): Unit = {
putIndex2()
}
}
case class User(id: Long, name: String)
case class Movie(id: Long, name: String, doubanScore: Float, actorList: util.List[User])
总结
一只勤奋的菜鸡