mongodb存储数据

继续使用MongoDB进行 NoSQL之旅,我想谈一谈一个经常出现的特定用例:存储分层文档关系。 MongoDB是很棒的文档数据存储,但是如果文档具有父子关系,该怎么办? 我们可以有效地存储和查询此类文档层次结构吗? 肯定的答案是,我们可以。 MongoDB对如何在MongoDB中存储树提出了一些建议。 那里描述的并且被广泛使用的一种解决方案是使用物化路径。

让我通过提供非常简单的示例来解释其工作原理。 如前几篇文章所述,我们将使用最近发布的Spring Data MongoDB项目的1.0版来构建Spring应用程序。 我们的POM文件包含非常基本的依赖关系,仅此而已。

4.0.0mongodbcom.example.spring0.0.1-SNAPSHOTjarUTF-83.0.7.RELEASEorg.springframework.dataspring-data-mongodb1.0.0.RELEASEorg.springframeworkspring-beansorg.springframeworkspring-expressioncglibcglib-nodep2.2log4jlog4j1.2.16org.mongodbmongo-java-driver2.7.2org.springframeworkspring-core${spring.version}org.springframeworkspring-context${spring.version}org.springframeworkspring-context-support${spring.version}org.apache.maven.pluginsmaven-compiler-plugin2.3.21.61.6

为了正确配置Spring上下文,我将使用利用Java类的配置方法。 我越来越提倡使用这种样式,因为它提供了强大的类型化配置,并且大多数错误都可以在编译时发现,而无需再检查XML文件。 这里看起来像:

package com.example.mongodb.hierarchical;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoFactoryBean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;@Configuration
public class AppConfig {@Beanpublic MongoFactoryBean mongo() {final MongoFactoryBean factory = new MongoFactoryBean();factory.setHost( "localhost" );return factory;}@Beanpublic SimpleMongoDbFactory mongoDbFactory() throws Exception{return new SimpleMongoDbFactory( mongo().getObject(), "hierarchical" );}@Beanpublic MongoTemplate mongoTemplate() throws Exception {return new MongoTemplate( mongoDbFactory() );}@Beanpublic IDocumentHierarchyService documentHierarchyService() throws Exception {return new DocumentHierarchyService( mongoTemplate() );}
}

很好,很清楚。 谢谢, 春天的家伙! 现在,所有样板文件已准备就绪。 让我们转到有趣的部分:文档。 我们的数据库将包含“文档”集合,其中存储了SimpleDocument类型的文档。 我们使用用于SimpleDocument POJO的Spring Data MongoDB批注对此进行描述。

package com.example.mongodb.hierarchical;import java.util.Collection;
import java.util.HashSet;import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;@Document( collection = "documents" )
public class SimpleDocument {public static final String PATH_SEPARATOR = ".";@Id private String id;@Field private String name;@Field private String path;// We won't store this collection as part of document but will build it on demand@Transient private Collection< SimpleDocument > documents = new HashSet< SimpleDocument >();public SimpleDocument() {}public SimpleDocument( final String id, final String name ) {this.id = id;this.name = name;this.path = id;}public SimpleDocument( final String id, final String name, final SimpleDocument parent ) {this( id, name );this.path = parent.getPath() + PATH_SEPARATOR + id;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPath() {return path;}public void setPath(String path) {this.path = path;}public Collection< SimpleDocument > getDocuments() {return documents;}
}

让我在这里解释几件事。 首先,魔术属性路径 :这是构建和查询层次结构的关键。 路径包含所有文档父级的标识符,通常以某种分隔符(在我们的情况下为)分隔 (点) 。 以这种方式存储文档层次结构关系可以快速构建层次结构,进行搜索和导航。 其次,注意临时文档集合:此非持久集合由持久提供者构造,并包含所有后代文档(以防万一,还包含自己的后代)。 让我们通过查找find方法实现来实际观察它:

package com.example.mongodb.hierarchical;import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;public class DocumentHierarchyService {private MongoOperations template;public DocumentHierarchyService( final MongoOperations template ) {this.template = template;}@Overridepublic SimpleDocument find( final String id ) {final SimpleDocument document = template.findOne(Query.query( new Criteria( "id" ).is( id ) ),SimpleDocument.class);if( document == null ) {return document;}return build(document,template.find(Query.query( new Criteria( "path" ).regex( "^" + id + "[.]" ) ),SimpleDocument.class));}private SimpleDocument build( final SimpleDocument root, final Collection< SimpleDocument > documents ) {final Map< String, SimpleDocument > map = new HashMap< String, SimpleDocument >();for( final SimpleDocument document: documents ) {map.put( document.getPath(), document );}for( final SimpleDocument document: documents ) {map.put( document.getPath(), document );final String path = document.getPath().substring( 0, document.getPath().lastIndexOf( SimpleDocument.PATH_SEPARATOR ) );if( path.equals( root.getPath() ) ) {root.getDocuments().add( document );} else {final SimpleDocument parent = map.get( path );if( parent != null ) {parent.getDocuments().add( document );}}}return root;}
}

如您所见,要获得具有整个层次结构的单个文档,我们只需要运行两个查询(但是更优化的算法可以将其缩减为一个查询)。 这是一个示例层次结构,以及从MongoDB读取根文档的结果

template.dropCollection( SimpleDocument.class );final SimpleDocument parent = new SimpleDocument( "1", "Parent 1" );
final SimpleDocument child1 = new SimpleDocument( "2", "Child 1.1", parent );
final SimpleDocument child11 = new SimpleDocument( "3", "Child 1.1.1", child1 );
final SimpleDocument child12 = new SimpleDocument( "4", "Child 1.1.2", child1 );
final SimpleDocument child121 = new SimpleDocument( "5", "Child 1.1.2.1", child12 );
final SimpleDocument child13 = new SimpleDocument( "6", "Child 1.1.3", child1 );
final SimpleDocument child2 = new SimpleDocument( "7", "Child 1.2", parent );template.insertAll( Arrays.asList( parent, child1, child11, child12, child121, child13, child2 ) );...final ApplicationContext context = new AnnotationConfigApplicationContext( AppConfig.class );
final IDocumentHierarchyService service = context.getBean( IDocumentHierarchyService.class );final SimpleDocument document = service.find( "1" );
//  Printing document show following hierarchy:
//
//  Parent 1
//   |-- Child 1.1
//     |-- Child 1.1.1
//     |-- Child 1.1.3
//     |-- Child 1.1.2
//       |-- Child 1.1.2.1
//   |-- Child 1.2

而已。 简单一个强大的概念。 当然,在路径属性上添加索引将大大加快查询速度。 有很多改进和优化,但是基本思想现在应该很清楚。

参考:在Andriy Redko {devmind}博客上,由我们的JCG合作伙伴 Andrey Redko 在MongoDB中存储分层数据 。

翻译自: https://www.javacodegeeks.com/2012/01/storing-hierarchical-data-in-mongodb.html

mongodb存储数据

mongodb存储数据_在MongoDB中存储分层数据相关推荐

  1. 机器学习 处理不平衡数据_在机器学习中处理不平衡数据

    机器学习 处理不平衡数据 As an ML engineer or data scientist, sometimes you inevitably find yourself in a situat ...

  2. node sqlite 插入数据_安卓手机中的应用数据都保存在哪些文件中?

    随笔 知识 案例 声音 其他 编者按 手机取证,品牌是一方面,从操作系统入手是另外一个渠道.手机中的重要数据基本上都以轻量数据库的形式保存在本地,也就是经常讲的sqlite db文件中. 从推特上得知 ...

  3. html中获取modelandview中的json数据_从Bitmap中获取YUV数据的两种方式

    从Bitmap中我们能获取到的是RGB颜色分量,当需要获取YUV数据的时候,则需要先提取R,G,B分量的值,然后将RGB转化为YUV(根据具体的YUV的排列格式做相应的Y,U,V分量的排列) 所以这篇 ...

  4. mysql 动态sql 解析json数据_在SQL 中生成JSON数据

    这段时间接手一个数据操作记录的功能,刚拿到手上的时候打算用EF做,后来经过仔细考虑最后还是觉定放弃,最后思考再三决定: 1.以模块为单位分表.列固定(其实可以所有的操作记录都放到同一个表,但是考虑到数 ...

  5. mysql树状查询优化_解析SQL中树形分层数据的查询优化

    在数据查询中,从2008开始SQL Server提供了一个新的数据类型hierarchyid,专门用来操作层次型数据结构. hierarchyid 类型对层次结构树中有关单个节点的信息进行逻辑编码的方 ...

  6. 云中数据_免费备份和共享云中数据的最佳网站

    云中数据 We've been told many times how important backups are, although we may not realize it until it's ...

  7. Java_Hive自定义函数_UDF函数清洗数据_清洗出全国的省份数据

    Java_Hive_UDF函数清洗数据_清洗出全国的省份数据 最近用Hadoop搞数据清洗,需要根据原始的地区数据清洗出对应的省份数据,当然我这里主要清洗的是内陆地区的数据,原始数据中不包含港澳台地区 ...

  8. (C语言)已知顺序表L1,L2中数据由小到大有序,请用尽可能快的方法将L1与L2中的数据合并到L3中,使数据在L3中按升序排列。

    (C语言)已知顺序表L1,L2中数据由小到大有序,请用尽可能快的方法将L1与L2中的数据合并到L3中,使数据在L3中按升序排列. 输入样例: 5 2 4 9 10 11 6 1 2 4 6 7 8 输 ...

  9. mongodb 存储过程 遍历表数据_使用MongoDB存储数据

    在 Ubuntu14.04 上安装 Install MongoDB Community Edition 1. Import the public key used by the package man ...

最新文章

  1. 怎样理解公钥,私钥和数字签名
  2. SAP Fiori Elements里Edit按钮点击之后的后台实现
  3. c语言实现英文文本编辑器_用flutter实现富文本编辑器(二)
  4. 元素分类--块级元素(特点:独占一行, 宽高边距可改)
  5. 用URLGather来管理和保存你的页面
  6. JavaScript在内层循环中断外层循环
  7. 获取周一_周一个股精选:光伏概念、央企改革:太阳能(000591)
  8. eclipse maven项目 class类部署不到tomcat下_maven发布项目到远程tomcat
  9. Java反射学习笔记
  10. 动态规划求解最少硬币是多少?
  11. 半球贴180度全景图片
  12. 阿里矢量图标iconfont在微信小程序的使用
  13. win7计算机版本,目前win7有几个版本是多少种
  14. 极限理论总结01:随机变量的四种收敛、CMT及Slutsky定理
  15. 【Linux开发】Orange Pi上WiringPi的使用
  16. 计算机网络与新媒体就业前景,2018网络与新媒体专业就业前景和就业方向分析...
  17. 四川省国家级自然保护区功能区划
  18. 解决AJAX请求使PHP反应时间过长的问题
  19. linux 命令:su 详解
  20. JS高级程序设计(14)

热门文章

  1. 报错:The type javax.servlet.http.HttpServletRequest cannot be resolved
  2. 如何在工作繁重、睡眠较少的情况下保持旺盛精力?
  3. jvm(12)-java内存模型与线程
  4. Comparable and Comparator API
  5. jms面试题_最新的20多个JMS面试问答(2020)
  6. aws实例启动失败_AWS:启动安装了APOC的Neo4j实例
  7. aws lambda_带有API网关的AWS Lambda
  8. drill apache_使用Apache Drill深入研究当今的大数据
  9. 使用Apache Cassandra设置SpringData项目
  10. repl java9_Java 9抢先体验:与JShell进行动手实践– Java REPL