- 浏览: 2184110 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (682)
- 软件思想 (7)
- Lucene(修真篇) (17)
- Lucene(仙界篇) (20)
- Lucene(神界篇) (11)
- Solr (48)
- Hadoop (77)
- Spark (38)
- Hbase (26)
- Hive (19)
- Pig (25)
- ELK (64)
- Zookeeper (12)
- JAVA (119)
- Linux (59)
- 多线程 (8)
- Nutch (5)
- JAVA EE (21)
- Oracle (7)
- Python (32)
- Xml (5)
- Gson (1)
- Cygwin (1)
- JavaScript (4)
- MySQL (9)
- Lucene/Solr(转) (5)
- 缓存 (2)
- Github/Git (1)
- 开源爬虫 (1)
- Hadoop运维 (7)
- shell命令 (9)
- 生活感悟 (42)
- shell编程 (23)
- Scala (11)
- MongoDB (3)
- docker (2)
- Nodejs (3)
- Neo4j (5)
- storm (3)
- opencv (1)
最新评论
-
qindongliang1922:
粟谷_sugu 写道不太理解“分词字段存储docvalue是没 ...
浅谈Lucene中的DocValues -
粟谷_sugu:
不太理解“分词字段存储docvalue是没有意义的”,这句话, ...
浅谈Lucene中的DocValues -
yin_bp:
高性能elasticsearch ORM开发库使用文档http ...
为什么说Elasticsearch搜索是近实时的? -
hackWang:
请问博主,有用solr做电商的搜索项目?
Solr中Group和Facet的用法 -
章司nana:
遇到的问题同楼上 为什么会返回null
Lucene4.3开发之第八步之渡劫初期(八)
上篇介绍了ES嵌套模型使用场景和优缺点,本篇接着介绍关于ES嵌套的索引一些基本的操作,包括插入,追加,更新,删除,查询单独放下一篇文章介绍。
首先来看下如何添加数据,上篇提到了我们项目中有三个实体类分别是User,Quest,Kp。其关系是一对多对多,User里面有个List<Quest>字段可以包含多个Quest对象而每一个Quest对象又包含一个List<Kp>字段可以包含多个Kp实体,每个实体类本身又可以拥有多个自己的属性字段。
在这里其实也能感受到用动态索引模板的好处,就是我不要关注到底有多少个字段,我的实体类里面随时可以新增一个字段或多个字段进行索引,当然前提是你把动态模板的schema给定义好,这过程中也遇到一些问题,后面会在相关的文章中介绍。
现在我想添加"一条数据"进入索引,注意这里的一条数据,指的是向一次发送一次索引,因为嵌套索引它的嵌套文档每一个都是独立的document,所以看起来你向es索引了一条数据到其服务端后,doc的数量会大于1,这个其实很正常,下面解释一下。
现在我想索引一条User数据,但是User下面又包含了5个Quest实体,而每个Quest实体又包含了2个Kp知识点,那么最终到es里面显示的文档数量=1+5*2=11条数据,所以看起来你发送的一条数据,其实es服务端会把其拆分成独立的document,但是es会在内部标记他们的关系,在进行检索时可根据需要返回所有数据或者指定想要返回的数据。
(1)下面看下,如何添加一条数据的核心代码:
Kp k1=new Kp() Kp k2=new Kp() List<Kp> kps=new ArrayList<Kp>() kps.add(kp1) kps.add(kp2) //========================== Quest quest=new Quest() quest.setKps(kps) List<Quest> quests=new ArrayList<Quest>() quests.add(quest) //========================== User user=new User() user.setUid("001") user.setQuests(quests) //组装好Java Bean后,转成json向es服务端进行索引 String json=JSON.toJSON(user).toString();//这里用的FastJson框架 IndexResponse response=client.prepareIndex("Index", "type",user.getUid()).setSource(json).execute().actionGet();
可以发现插入的方法还是比较简单清晰的,就是将一个Java Bean转成json后进行索引,只要服务端有配置描述其schemal就可以成功插入
(2)在第二层嵌套数据里面添加一条新的数据到quests中
注意append操作,需要用到script来完成。
_ StringBuffer sb_json = new StringBuffer("ctx._source.quests += quest");//脚本主体 HashMap<String, Object> params = new java.util.HashMap<String, Object>()//Map组装 params.put("quest", JSON.toJSON(user.getQuests))//此处不能用JSON.toJSON(user.getQuests).toString方法,quest必须是一个对象,否则会报错 Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params)//组装脚本 client.prepareUpdate(dynamicIndexName, typeName, uid).setScript(script).execute().get() //发送请求
上面的代码,是向已经存在某个User给它新增了一个Quest对象,注意这个Quest对象里面,如果有Kp的数据,依旧也可以添加进来。
(3)在第二层嵌套数据里面删除一条quests数据
- StringBuffer sb_json = new Stri ngBuffer("ctx._source.quests.removeAll{it.qid == remove_id}"); java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>(); params.put("remove_id", "qid2");//此处不能用JSON.toJSON(user.getQuests).toString方法,quest必须是一个对象,否则会报错 Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params); client.prepareUpdate(dynamicIndexName, typeName, uid).setScript(script).execute().get();
(4)在第三层嵌套数据里面添加一条Kp数据
- StringBuffer sb_json = new StringBuffer("ctx._source.quests.findAll { if(it.qid==qid2||it.qid==qid3) { it.kps += kp5 } } "); java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>(); params.put("qid2", "qid2"); params.put("qid3", "qid3"); params.put("kp5",JSON.toJSON(kp1)); Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params); client.prepareUpdate(dynamicIndexName, typeName, uid).setScript(script).execute().get();
(5)在第三层嵌套数据里面删除一条Kp数据
- StringBuffer sb_json = new StringBuffer("ctx._source.quests.findAll { if(it.qid==qid2||it.qid==qid3) { it.kps.removeAll {it.kid==kid} } } "); //删除第三层数据 java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>(); params.put("qid2", "qid2"); params.put("qid3", "qid3"); params.put("kid", "kid3"); Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params); client.prepareUpdate(dynamicIndexName, typeName, uid).setScript(script).execute().get();
(6)更新第三层嵌套里面的数据
A:如果是字段数比较多,大范围更新,建议直接删除后添加
B: 如果字段数比较少,小范围更新,就使用下面的局部更新的API即可
- StringBuffer sb_json = new StringBuffer("ctx._source.quests.findAll { if(it.qid==qid3) { it.kps.findAll{ if(it.kid==kid){ it.kname=kname;it.kmd=kmd } } } } "); //更新第三层数据 java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>(); params.put("qid2", "qid2"); params.put("kname","地球的引力"); params.put("kid","kid5"); params.put("kmd",0.78); Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params); client.prepareUpdate(dynamicIndexName, typeName, uid).setScript(script).execute().get();
(7)同理更新第二层嵌套里面的数据
- StringBuffer sb_json = new StringBuffer("ctx._source.quests.findAll { if(it.qid==qid) { it.qtime=qtime } } "); //更新第三层数据 java.util.HashMap<String, Object> params = new java.util.HashMap<String, Object>(); params.put("qid", "qid1");//此处不能用JSON.toJSON(user.getQuests).toString方法,quest必须是一个对象,否则会报错 params.put("qtime",5558) Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params); client.prepareUpdate(dynamicIndexName, typeName, uid).setScript(script).execute().get();
总结:
本篇介绍了ES嵌套索引的添加,修改,删除的操作,我们不难发现都是用script脚本来完成的,ES默认用的是Groovy如果想更加深入的了解script脚本的各种语法,建议直接熟悉下Groovy的语法。虽然理论上我们通过script脚本来完成对无限嵌套索引的操作,但实际应用开发中,需要注意几点:
(1)不要出现太多层的嵌套结构,建议不要超过3级
(2)每层的嵌套结构List里面,不建议存储太多的数据,如果存的太多,删除,更新操作的时间都会是线性的,因为es需要遍历整个List(最坏情况下)找到你需要删或者改的数据
有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
技术债不能欠,健康债更不能欠, 求道之路,与君同行。
发表评论
-
复盘一个Elasticsearch排序问题的剖析
2019-07-15 21:12 1170最近线上的es查询的 ... -
elasticsearch里面bulk的用法
2018-04-09 20:23 1424上篇文章介绍了在es里 ... -
elasticsearch里面的关于批量读取mget的用法
2018-04-04 16:01 1834es的api除了提供了基本 ... -
elasticsearch的查询流程分析
2018-04-02 20:29 1330我们都知道es是一个分 ... -
如何在elasticsearch里面使用深度分页功能
2018-03-28 18:13 2022前面的文章提到过es默认的from+size的分页方式返回的结 ... -
如何在Elasticsearch里面使用索引别名
2018-03-27 20:37 1681在elasticsearch里面给index起一个alias ... -
如何优雅的全量读取Elasticsearch索引里面的数据
2018-03-26 20:27 7654### (一)scroll的介绍 有时候我们可能想要读取整个 ... -
关于elaticsearch中更新数据的几种方式
2018-03-21 19:00 969作为一个成熟的框架, ... -
Elasticsearch里面的segment合并
2018-03-20 17:50 2093通过前面的文章,我 ... -
Elasticsearch如何保证数据不丢失?
2018-03-19 20:52 2143上篇文章提到过,在elasticsearch和磁盘之间还有一层 ... -
为什么说Elasticsearch搜索是近实时的?
2018-03-16 19:41 9458通过前面两篇文章的介绍,我们大概已经知道了 Elasticse ... -
Elasticsearch如何动态维护一个不可变的倒排索引
2018-03-15 21:34 1140上一篇文章中介绍了Elasticsearch中是如何搜索文本 ... -
Elasticsearch如何检索数据
2018-03-14 20:11 1072我们都知道Elasticsearch是一个全文检索引擎,那么它 ... -
如何备份ElasticSearch索引数据到HDFS上
2018-02-09 18:19 2424在ElasticSearch里面备份策略已经比较成熟了 ... -
Elasticsearch5.6.4集群搭建
2018-02-07 20:13 1341本次搭建的是一个三节点的集群 (一)es的安装 (1)下 ... -
如何使log4j生成json格式的log
2017-09-15 17:44 3826使用java开发项目时,log日志一般都是应用程序必不可少的一 ... -
理解elasticsearch的parent-child关系
2017-09-04 18:43 2841前面文章介绍了,在es里面的几种数据组织关系,包括array ... -
简述ElasticSearch里面复杂关系数据的存储方式
2017-08-18 20:10 2414在传统的数据库里面,对数据关系描述无外乎三种,一对一,一对多和 ... -
使用Java Rest Client操作Elasticsearch
2017-08-09 19:42 2272Elasticsearch作为一个成熟的开源框架,对主流的多种 ... -
ElasticSearch里面的偏好查询
2017-06-22 17:17 1306在es查询的时候我们可 ...
相关推荐
5. 文档模型:Elasticsearch 存储的是 JSON 文档,这种模式允许存储复杂的数据结构,如嵌套字段和数组。 6. 自动分词:Elasticsearch 内置了多种语言的分词器,可以对不同语言的文本进行预处理,便于搜索。 7. ...
4. **数据模型**:Elasticsearch 基于JSON文档存储,支持丰富的数据类型,如字符串、数字、日期等,并且可以进行复杂的数据结构分析,如嵌套字段和数组字段。 5. **全文搜索**:Elasticsearch 提供了强大的全文搜索...
为了提高搜索效率与用户体验,越来越多的企业选择使用Elasticsearch(简称ES)作为其商品数据的搜索引擎。本文将详细介绍如何在ES中构建有效的SKU(Stock Keeping Unit,库存量单位)存储模型,并对给定的存储模型...
3. **文档模型**:Elasticsearch 基于文档数据库模型,支持嵌套数据结构,如数组和对象,允许存储复杂的数据类型。 4. **倒排索引**:基于Lucene的倒排索引技术是Elasticsearch快速全文检索的基础。每个文档的...
Elasticsearch最大的优势之一是其易用的Restful API,为开发者提供了极其便利的操作接口。 Elasticsearch的生态圈中有几个重要的组件,例如ELK(Elasticsearch、Logstash和Kibana),它们通常被一同使用来实现数据...
9. **文档模型**:Elasticsearch采用JSON文档作为数据模型,支持嵌套字段和数组,方便处理复杂的数据结构。 10. **聚合分析**:除了基本的搜索功能,Elasticsearch还提供丰富的聚合功能,如术语聚合、平均值聚合等...
Elasticsearch,简称ES,是一款基于Lucene的分布式、RESTful风格的搜索和数据分析引擎,广泛应用于大数据处理和全文检索领域。本教程将深入探讨Elasticsearch的高级特性和进阶技巧,帮助用户提升对这一强大工具的...
以上是千锋Elasticsearch 6教程的部分核心知识点,通过深入学习和实践,你可以掌握Elasticsearch的基本使用以及在实际项目中的应用技巧。在学习过程中,结合提供的实战教程资料,将有助于更好地理解和掌握这些概念。
然后,在Django项目中创建一个搜索模型,该模型将映射到Elasticsearch索引。通过Django的信号处理器或自定义管理命令,可以实现数据的自动同步。搜索查询则可以通过Elasticsearch的DSL(Domain Specific Language)...
**Elasticsearch 全文检索概述** Elasticsearch 是一种高度可扩展的开源全文搜索引擎,基于 Apache Lucene 构建。...在实际应用中,了解并掌握这些基本概念对于优化 Elasticsearch 集群的性能和稳定性至关重要。
4. **数据模型**:Elasticsearch的数据模型包括文档(documents)、类型(types)和索引(indices)。在6.8.6版本中,已经废弃了类型概念,每个索引只包含一种类型,即文档。文档是存储数据的基本单元,它们是JSON...
Elasticsearch 是一款高度可扩展的全文搜索引擎,广泛应用于数据搜索和分析场景。在实际应用中,优化Elasticsearch的搜索速度是确保高效服务的关键。本文将深入探讨影响Elasticsearch查询性能的因素,并提出一系列...
Elasticsearch(简称ES)是一种开源的、基于Lucene的全文搜索引擎,它提供了一个分布式、多用户环境下的搜索和分析引擎服务。ES以其高效、可扩展、实时的搜索能力在大数据处理领域备受青睐,广泛应用于日志分析、...
- 遵循Elasticsearch的数据模型,如避免过于复杂嵌套的文档结构。 - 使用合适的分析器进行文本字段的索引,以实现预期的搜索行为。 通过上述步骤,你可以在Java中构建一个完整的Elasticsearch辅助类,用于高效地...
4. **文档模型**:Elasticsearch以JSON文档的形式存储数据,支持复杂的数据结构,如嵌套字段和数组。 5. **分词和分析**:内置的Lucene分析器支持多种语言的文本分析,能够将输入文本拆分为关键词,为全文搜索提供...
Elasticsearch 提供了命令行工具 `curl` 或者 ` Sense` 插件来进行测试和操作。 总之,Elasticsearch 6.5.4 作为一个高效、灵活的搜索引擎,通过 RESTful API 提供了强大的搜索、分析和分布式处理能力,是大数据...
1. **节点(Node)**:Elasticsearch运行的基本单元,每个节点存储数据并参与集群的操作。 2. **集群(Cluster)**:由多个节点组成,负责协调和分配任务,确保数据的分布和冗余。 3. **索引(Index)**:类似于数据库中的...
5. **文档型数据库**:Elasticsearch以JSON文档的形式存储数据,每条数据都是一个独立的JSON对象,具有灵活的数据模型。这使得它非常适合处理结构化和半结构化的数据。 6. **自动分词**:Elasticsearch内置了多种...
PG同步PostgreSQL到Elasticsearch同步是一个中间件,用于轻松地将数据从同步到 。 它允许您将保留为事实来源,并在公开结构化的非规范化文档。 对嵌套实体的更改将传播到 。 然后,PGSync的高级查询生成器会根据您的...