mongodb crud注意点

一、

原始数据: 
{ 
    "_id" : ObjectId("56a039fd8b04f95d2a8bbc95"), 
    "title" : "I Have a Dream", 
    "comments" : [
        {
            "author" : "joe", 
            "score" : NumberInt(3), 
            "comment" : "nice post"
        }, 
        {
            "author" : "mary", 
            "score" : NumberInt(6), 
            "comment" : "terrible post"
        }
    ]
}
{ 
    "_id" : ObjectId("56a03a858b04f95d2a8bbc98"), 
    "title" : "I Have a Dream2", 
    "comments" : [
        {
            "author" : "joe", 
            "score" : NumberInt(6), 
            "comment" : "nice post2"
        }, 
        {
            "author" : "mary", 
            "score" : NumberInt(6), 
            "comment" : "terrible post2"
        }
    ]
}
{ 
    "_id" : ObjectId("56a03a858b04f95d2a8bbc99"), 
    "title" : "I Have a Dream3", 
    "comments" : [
        {
            "author" : "joe", 
            "score" : NumberInt(2), 
            "comment" : "nice post3"
        }, 
        {
            "author" : "joe", 
            "score" : NumberInt(8), 
            "comment" : "terrible post3"
        }
    ]
}

---现在要查询“由Joe发表的5分以上的评论”---

//查询结果不符,因为内嵌文档匹配要求整个文档完全匹配,而这不会匹配"comment"键。
db.blog.find({"comments":{"author":"joe","score":{"$gte":5}}})

/*
同样也不会达到目的。因为符合author条件的评论和符合score条件的评论可能不是同一条评论。也就是说,会返回刚才显示的那个文档。因为"author" : "joe"在第一条评论中匹配了,"score" : 6在第二条评论中匹配了
*/
db.blog.find({"comments.author" : "joe", "comments.score" : {"$gte" : 5}})

//正确查询
db.blog.find(
    {
        "comments" : {
            "$elemMatch" : {
                "author" : "joe",
                "score":{
                    "$gte":5
                }
            }
        }
    }
)

mongodb匹配都是以整个document为单元获取的,例如以上例子,并不只是单单获取“由Joe发表的5分以上的评论”这个数组当中的嵌套的document

{
        "comments" : {
            "$elemMatch" : {
                "author" : "joe",
                "score":{
                    "$gte":5
                }
            }
        }
    },
{
  //以下这个projection,注意有“$”,表示只展示数组中匹配的document
 "comments.author.$": 1,
 "_id": 0
}

result:
{ 
    "comments" : [
        {
            "author" : "joe", 
            "score" : NumberInt(6), 
            "comment" : "nice post2"
        }
    ]
}
{ 
    "comments" : [
        {
            "author" : "joe", 
            "score" : NumberInt(8), 
            "comment" : "terrible post3"
        }
    ]
}

//不加“$”的结果
{ 
    "comments" : [
        {
            "author" : "joe"
        }, 
        {
            "author" : "mary"
        }
    ]
}
{ 
    "comments" : [
        {
            "author" : "joe"
        }, 
        {
            "author" : "joe"
        }
    ]
}

以上内容来自 http://www.jianshu.com/p/e59cd2dc5274

db.data.insert({name:'a', num:[12,123,22,34,1]});

//指定大小为2
db.data.find({num:{$size:2}})

//$size有一个缺陷,就是无法查询某个范围的大小
db.data.find({num:{$size:{$gt:2}}}); //错误

[数组大小小于3]
//这种方法具有很大的灵活性,但是速度会慢一些
db.data.find({ $where: "this.num.length < 3" })

//另外一个比较高效的方法是判断数组中的某个指定索引的元素是否存在,例如如果要求数组大小小于3
db.data.find({ "num.2": {$exists:0} })
//原始数据:
{
    "_id" : NumberLong(1181675746),
    "shard_qty" : 4,
    "goods_qty" : 0,
    "shop_qty" : 0,
    "favorite_qty" : 4,
    "favorite_shards" : [ 
      {
            "sid" : NumberLong(580),
            "favorite_dt" : ISODate("2015-06-26T12:13:06.405+08:00"),
            "is_attention" : true
        }, 
      {
            "sid" : NumberLong(579),
            "favorite_dt" : ISODate("2015-06-26T12:13:06.405+08:00"),
            "is_attention" : true
        }, 
        {
            "sid" : NumberLong(578),
            "favorite_dt" : ISODate("2015-06-26T12:13:06.405+08:00"),
            "is_attention" : true
        }, 
        {
            "sid" : NumberLong(577),
            "favorite_dt" : ISODate("2015-06-26T13:20:48.449+08:00"),
            "is_attention" : true
        }
    ]
}

//想获取的结果:
{
    "_id" : NumberLong(1181675746),
    "favorite_shards" : [ 
      {
            "sid" : NumberLong(578),
            "favorite_dt" : ISODate("2015-06-26T12:13:06.405+08:00"),
            "is_attention" : true
        }, 
        {
            "sid" : NumberLong(577),
            "favorite_dt" : ISODate("2015-06-26T13:20:48.449+08:00"),
            "is_attention" : true
        }
    ]
}

//条件
{'favorite_shards.sid': {
        '$in':[NumberLong(577),NumberLong(578)]
        }
    }
}
//返回数组中匹配的项
db.test.aggregate({"$unwind":"$favorite_shards"}, {"$match":{"favorite_shards.sid": {"$in": [NumberLong(578), NumberLong(577)]}}},  {"$group": {"_id": "$_id", "favorite_shards":{'$push': "$favorite_shards"}}})

 reference:mongodb 内嵌数组查询问题: 如何限定返回与条件匹配的数组

猜你喜欢

转载自kinghoo.iteye.com/blog/2270618