mongo 中的数组操作

背景

mongo中的数组可以应对复杂的业务场景,不需要先查出后更新,或者先找到一个大范围的集合然后进一步过滤,可以直接更新或直接找到目标文档。

一个例子

假设我们有个用户发布文章的平台,里面的文档都类似这样

{
  "_id": "5f86e6a5323f7d11e96f5fdf",
  "articleId": 1,
  "title": "如何问候",
  "content": "这样这样这样",
  "tag": [
    "生活",
    "股市",
    "营销"
  ],
  "comments": [
    {
      "commentId": 1,
      "content": "你好么",
      "Author": "金庸",
      "like_count": 1
    },
    {
      "commentId": 2,
      "content": "吃了么",
      "author": "古龙",
      "like_count": 2
    }
  ]
}
  • 1.找到标签为“股市”的所有文章(相当于php 的 in_array)

    db.articles.find({"tag":"股市"})
    
  • 2.找到所有有两个标签的文章(相当于php 的 count($arr) == 2)

     db.articles.find({"tag":{$size:2}})
    
  • 3.找到所有包含营销和股市这两个标签的文章

    db.articles.find({"tag":{$all:["营销","股市"]}})
    
  • 4.给文章id为1的添加一个标签,并且保证标签不重复

    db.articles.updateOne({"articleId":1}, {"$addToSet":{tag:"交际"}})
    
  • 5.给文章id为1的一次添加两个标签,并且保证标签不重复

    db.articles.updateOne({"articleId":1}, {"$addToSet":{tag:{$each:["政治",  "国情"]}}})
    
  • 6.删除掉文章id为1的营销标签

    db.articles.updateOne({"articleId":1}, {
     "$pull":{
     	"tag": {$in :["营销"]}
     }
    })
    
  • 7.给文章id为1的新增一个评论,往后累加

    db.articles.updateOne({"articleId":1}, {
    "$push":{
         "comments": {
             "commentId": 3,
             "content": "吃好了么",
             "author": "古龙",
             "like_count":0
         }
     }
    })
    
  • 8.给文章id为1的新增一个评论,但要根据点赞数排序点赞数高的放到前面

     db.articles.updateOne({"articleId":1}, {
     	  "$push":{
              "comments": {"$each":[{
                  "commentId": 3,
                  "content": "吃好了么",
                  "author": "古龙",
                  "like_count":0
             }], $sort: {like_count: -1}}
         }   
    })
    
  • 9.给文章id为1的新增一个评论,放到最开头

     db.articles.updateOne({"articleId":1}, {
     	  "$push":{
              "comments": {
                 "$each":[{
                     "commentId": 3,
                     "content": "吃好了么",
                     "author": "古龙",
                     "like_count":0
                 }],  $position: 0
               }   
         }
    })
    
  • 10.找到所有存在点赞数大于5的文章,或有金庸评论的文章

    db.articles.find({
     "comments":{
        $elemMatch: {
          "author":"金庸"
        }
     }
    })
    
  • 11.更新文章id为1的评论id为2的点赞数加1

    db.articles.updateOne(
    { articleId: 1, "comments.commentId": 2 },
    { $inc: { "comments.$.like_count" : 1 } }
    )
    
  • 12.找到所有标题或内容包含武侠这个字符串的文章

    db.articles.find(
     {
       "$or": [
          {title:{$regex:"武侠"}},
          {content:{$regex:"武侠"}}
       ]
     }
    )
    

限制

$slice 只能搭配$push 使用 如果$addToSet就用不了。对于数组中都是对象的情况mongo不要求每个对象类型一样,如果有脏数据影响很大。数组对于下标更新没有检查边界。
mongo中无论子文档还是文档本身的key都不要带 “.”, 否则使用按照下标或者更新对象类型 会有解析问题(object.field 或 array.0), 如果不能保证就不要让数据本身作为key(key都写死,这样用起来也好用)

参考

https://docs.mongodb.com/manual/reference/operator/update-array/
https://docs.mongodb.com/manual/tutorial/query-array-of-documents/
https://docs.mongodb.com/manual/tutorial/query-arrays/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值