mongodb能不能搜索mongodb多层嵌套更新子文档中的任意内容?

[转载]mongodb&子文档查询
首先我的数据库里有两个文档,每个文档里都有2个嵌套的数组:
如果我想查询comments里score大于5的记录:
testProvider.find({"comments.score":{"$gt":5}},{},function(err,
&console.log(result);
返回了查找到的记录,说明了查找有效果了:
这样查找返回的数据都是把匹配的整个文档返回过来了。
如果我觉得其中有个字段是没必要返回给我的可以设置这个字段为0:
testProvider.find({"comments.score":{"$gt":5}},{'comments.others':0},function(err,
console.log(JSON.stringify(result));
可以看到返回的结果中已经没有others这个字段了
如果我想查询comments数组里面的某个子文档中others数组里面name为a的记录:
testProvider.find({"comments.others.name":'a'},{},function(err,
console.log(JSON.stringify(result));
返回的结果中的一部分如下图:
从上面的几个示例中可以看到我想要查找某个符合条件的子文档时可以直接一直用'.'号表示下去而不用管其中是否有数组,如:{"comments.others.name":'a'}
一些高级的查询语法看这一篇:
1、使用"$size"可以查询指定长度的数组
查询数组长度为3的数组db.users.find({"emails":{"$size":3}})
常见的查询是数组长度范围的查询."$size"并不能与其他查询子句组合(如:"$gt"),但是这种查询可以通过
在文档中添加一个"size"键的方式来实现.这样每一次向指定数组添加元素的时候,同时增加"size"值.原来这样
的更新: &db.users.update({"$push":{"emails":""}})
变成这样的更新:
&db.users.update({"$push":{"emails":""},"$inc":{"size":1}})
这样就可以这样查询了&db.users.find({"size":{"$gt":3}})
2、使用"$slice"查询
find的第二个参数是可选的,可以指定返回那些键,"$slice"返回数组的一个子集合
返回emails数组的前两个元素
&&db.users.find({"userName":"refactor"},{"emails":{"$slice":2}})
返回emails数组的后两个元素
&&db.users.find({"userName":"refactor"},{"emails":{"$slice":-2}})
返回emails数组的第2个和第11个元素.如果数组不够11个,则返回第2个后面的所有元素
db.users.find({"userName":"refactor"},{"emails":{"$slice":[1,10]}})
"$slice"默认将返回文档中的所有键.&
3、要正确指定一组条件,而不用指定每个键,要使用"$elemMatch".这种模糊的命名条件能用来部分指定匹配数组中
的单个内嵌文档的限定条件.正确写法应该是:
db.blog.find(
    "comments":
      "$elemMatch":
      {
        "author":"refactor",
        "score":{"$gte":5}
      }
"$elemMatch"将限定条件进行分组,仅当需要对一个内嵌文档的多个键操作时才会用到.
4."$where"查询
"$where"可以执行任意javascript作为查询的一部分.这使得查询能做(几乎)任何事情.
最典型的应用就是比较文档中的两个键的值是否相等.
如:db.blog.insert({"title":"refactor","content":"refactor"})
db.blog.insert({"title":"refactor1","content":"refactor
content"})
第一个文档title键和content键的值相同.要返回该文档.
db.blog.find(
    "$where":function()
          {
            for(var current in this)
            {
              for(var other in this)
              {
                if(current!=other&&this[current]==this[other])
                {
                  
                }
              }
            }
            
          }
如果函数返回true,文档就作为结果的一部分被返回.
上面是用一个函数,也可以用一个字符串指定"$where"查询.下面两种方式是等价的:
db.blog.find({"$where":"this.x+this.y==10"})
db.blog.find({"$where":"function(){return
this.x+this.y==10;}"})
不是非常必要时,应避免"$where"查询.它在速度上要比常规查询慢的多.每个文档都要从BSON转换成
javascript对象,然后通过"$where"的表达式来运行.它还不能利用索引.
将常规查询作为前置过滤,与"$where"组合使用才能不牺牲性能,如果有可能的话,用索引根据非"$where"
子句进行过滤,"$where"只用于对结果进行调优
上面的4个查询转自:
更新子文档:
在更新子文档时和查询时又有所不同(遇到数组时多加一个$符号):
testProvider.update({"comments.score":4},{'$set':{'comments.$.score':1}},{multi:true,w:
1},function(err, numberUpdated)
& & console.log("numberUpdated: ",
numberUpdated);
查询下可以发现结果已经改变了:
如果我想往一个子文档的数组中插入一个子文档时可以使用push:
testProvider.update({"comments.score":1},{'$push':{'comments.$.others':{"name":"j","age":"24"}}},{multi:true,w:
1},function(err, numberUpdated) {
console.log("numberUpdated: ", numberUpdated);
查询之后可以发现comments.others里多了一个子文档,表明已经插入进去了:
如果我想把刚刚插入的子文档删除时,可以使用pull:
testProvider.update({"comments.score":1},{'$pull':{'comments.$.others':{"name":"j"}}},{multi:true,w:
1},function(err, numberUpdated) {
console.log("numberUpdated: ", numberUpdated);
查询之后可以发现结果已经改变:
注意:如下图所示pull值中的key对应的值必须为json格式的:
我在使用的过程中还发现在遇到数组时使用'.$'符号时每个里面只能用一次;如上图的错误写法中就含有2个'.$'符号。所以如果子文档里嵌套有2个乃至更多数组时,很难准确的对嵌套的数组中的某一个元素进行更新。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Mongodb多层嵌套数组如何精确查询(内容处为格式化的json截图,评论里面是json的内容)?_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
Mongodb多层嵌套数组如何精确查询(内容处为格式化的json截图,评论里面是json的内容)?
json格式就贴图如上了,现在我想查出所有hobbyName是电影的人员的信息(返回的应该是个包含name,sex,hobbies的集合);想通过下个语句查出所有hobbyName是音乐的人名的集合现在我的问题是如果嵌套多层数组的话db.getCollection('person').find({&excelID&:&10...
我有更好的答案
感觉你设计的数据结构太复杂,内嵌文档太多层了,为什么不一个学生一条记录呢,这样设计部是更简洁吗,查询统计什么的都很简单,你现在的文档一次查询是得不到你想要的结构的,只能用聚合看能不能实现。
采纳率:71%
来自团队:
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。}

我要回帖

更多关于 mongodb 嵌套文档 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信