mongoDB 简单操作

最近在公司做一个数据仓储等项目,在项目中使用到以前没有用过的mongoDB,下面对使用mongodb中的一些技巧进行记录和分享。文章中的示例以mongo的原生sql和Java进行说明(ps:会不断进行更新)

查询

  查询有两个点需要了解,一个是查询内嵌文档,另一个则是返回数据的筛选。查询部分就这两个点展开描述。
内嵌文档查询
  内嵌文档由是有深度的层级结构,普通的表示查询不能在深度上进行查询操作。mongo提供一种点表示法来处理内嵌文档的操作需求。点表示法是指通过"字段1.字段2.字段3"这样的方式来定位查询,mongo在字段定位上全面支持点表示法,如更新的字段、新增的字段等。另外上述表述找到字段1下面的字段2下面的字段3来进行相应的处理操作。
/* 1 */
{
    "_id" : ObjectId("59a3edde06edb18e9ecb3252"),
    "name" : "jack",
    "address" : {
        "province" : "上海",
        "region" : "浦东新区"
    },
    "age" : 23.0
}
上面是mongo里面的一条内嵌文档数据,匹配地址为上海的人的sql为:
db.study_test.find({"address.province":"上海"})
所以在mongo中,数据的key值是不能有“.”的,点是mongo的关键字。

#####

限定返回字段
因为mongo中的内嵌文档数据一般比较大,如果不限制返回的字段,按照关系型数据库的语法操作的话,会返回整条数据,这里需要说名的是:mongo的查询定位的是一条数据,但是不能限定该条数据中的部分数据,及如果不进行返回字段限定操作,则每次query返回的最小单位为一条整的数据,及有一个"_id"的完整数据.
现在用上例数据再次进行演示。查找jack所处的区(region)

	   db.study_test.find({"name":"jack"},{"address.region":1})
	   查询结果显示:
	    /* 1 */
		{
	    "_id" : ObjectId("59a3edde06edb18e9ecb3252"),
	    "address" : {
	        "region" : "浦东新区"
	    }
}

0表示不显示,大于0表示显示该字段。很明显,这样的操作就限定了返回的数据,只返回了满足条件的jack的region。

干货分享
  1. 限定返回字段后,其返回的层级结构并不会变,及深度不会变,在取值的时候需要按照限定的键值更具点切割后循环取值。如限定的key为:address.region:1,如果需要取到region的值,就需要将address.region按照"."进行切割,然后去取address的值,再去取region的值。在Java中可以将每步取出来的结果转为DBObject。
    如果数据库中存储的值是一串数组,则取出的结果集为以序号为key数组中的每一行数据为value的键值对。所以在结果集中数组的key为1.2.3…的序号值
    示例数据如下:
	数据录入语句
	  db.study_test.update({"name" : "jack"},{$set:{"dataType":[{"name":"王者农药","star":"5星"},
    {"name":"红警","star":"4星"},{"name":"魔兽","star":"4星"}]}})
mongo中的树形结构:
{
    "_id" : ObjectId("59a3edde06edb18e9ecb3252"),
    "name" : "jack",
    "books" : [ 
        "程序员的修养", 
        "JAVA从入门到转行"
    ],
    "games" : [ 
        {
            "name" : "王者农药",
            "star" : "5星"
        }, 
        {
            "name" : "红警",
            "star" : "4星"
        }, 
        {
            "name" : "魔兽",
            "star" : "4星"
        }
    ]
}

通过Java获取games的值,下面是debug模式下的显示:

![这里写图片描述](https://img-blog.csdnimg.cn/img_convert/f82d9ed068d77a3aa1487dc63c9203d3.png)
games下面有三个key值,对应三个游戏的序号。所以需要通过游标先获取整体的数据,在取key为games对应的值,然后再次通过keySet()遍历来取最终存储在mongo中的三个游戏。 2. 获取key值 mongo中一般存储了大量内嵌文档数据,key值常常是一个重要的标识数据,是项目中有单独需求。但是mongodb并不支持类似map的keySet来获取key,所以我们只能通过获取该key下的所有数据,然后在进行key的获取。考虑到mongo内嵌文档的数据量,所以在获取key的过程中不可避免的获取大量无用数据,所以此获取过程应该通过工具类或私有方法的手段来将其使用后赶紧释放,这里释放的原理是基于JVM的方法栈的出栈对内存的释放,不是JVM的则需要通过另外的方式实现。 ###

更新

更新需要注意的是insert ,save ,update的使用。insert是插入一条新纪录,save是进行文档替换,update是进行字段更新。所以insert是直接insert(document),而save和update都需要进行查找定位(query,update/save);在使用上,mongo提供了许多的处理器,使用都是以\$开头,如修改器set的使用是:$set,其运行机制是查找query的document的需要set的字段,如果该字段存在,就更新这个字段的值,如果不存在就添加这个字段,并赋值。
db.study_test.update({"name" : "jack"},{$set:{"address":{"province":"上海","region":{"area":"浦东新区","detail":"世纪大道"}}}})

这条语句执行的效果就是更新jack的地址,如果jack没有地址就添加地址信息,如果有就将address更新为上海-浦东新区-世纪大道。
mongo还有许多的这种处理器,如针对数组进行添加的$addToSet、$push、删除数组中最后一个元素的$pop,以及删除字段的$unset,这里不展开说明。

2017-08-29 16:00更新

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值