嵌入文档的类型

嵌入文档有两种

一种为字典形式:

 "_id" : 1.0,
    "name" : "john",
    "address" : 
        {
            "province" : "Beijing",
            "city" :'Beijing',
            "couty" :'朝阳'
        }

另一种为列表的形式

也就是下面的这种形式

嵌入文档的查询

这里主要使用的列表的形式,字典的形式和列表的用法一样

{
    "_id" : 1.0,
    "zipcode" : "63109",
    "students" : [ 
        {
            "name" : "john",
            "school" : 102.0,
            "age" : 10.0
        }, 
        {
            "name" : "messi",
            "school" : 102.0,
            "age" : 11.0
        }, 
        {
            "name" : "jeff",
            "school" : 108.0,
            "age" : 15.0
        }
    ]
}

/* 2 */
{
    "_id" : 2.0,
    "zipcode" : "63110",
    "students" : [ 
        {
            "name" : "ajax",
            "school" : 100.0,
            "age" : 7.0
        }, 
        {
            "name" : "achilles",
            "school" : 102.0,
            "age" : 8.0
        }
    ]
}

/* 3 */
{
    "_id" : 3.0,
    "zipcode" : "63111",
    "students" : [ 
        {
            "name" : "jimi",
            "school" : 100.0,
            "age" : 8.0
        }, 
        {
            "name" : "messi",
            "school" : 102.0,
            "age" : 7.0
        }
    ]
}

/* 4 */
{
    "_id" : 4.0,
    "zipcode" : "63112",
    "students" : [ 
        {
            "name" : "barney",
            "school" : 102.0,
            "age" : 7.0
        }
    ]
}

使用.

'.'符号只能用在单一条件查询情况下

需求1:查询年龄为7的文档

db.getCollection('article').find({'students.age':7})

结果:

/* 1 */
{
    "_id" : 2.0,
    "zipcode" : "63110",
    "students" : [ 
        {
            "name" : "ajax",
            "school" : 100.0,
            "age" : 7.0
        }, 
        {
            "name" : "achilles",
            "school" : 102.0,
            "age" : 8.0
        }
    ]
}

/* 2 */
{
    "_id" : 3.0,
    "zipcode" : "63111",
    "students" : [ 
        {
            "name" : "jimi",
            "school" : 100.0,
            "age" : 8.0
        }, 
        {
            "name" : "messi",
            "school" : 102.0,
            "age" : 7.0
        }
    ]
}

/* 3 */
{
    "_id" : 4.0,
    "zipcode" : "63112",
    "students" : [ 
        {
            "name" : "barney",
            "school" : 102.0,
            "age" : 7.0
        }
    ]
}
结果

需求2:

查询年龄为7且school为100的文档

db.getCollection('article').find({'students.age':7,'students.school':100})
/* 1 */
{
    "_id" : 2.0,
    "zipcode" : "63110",
    "students" : [ 
        {
            "name" : "ajax",
            "school" : 100.0,
            "age" : 7.0
        }, 
        {
            "name" : "achilles",
            "school" : 102.0,
            "age" : 8.0
        }
    ]
}

/* 2 */
{
    "_id" : 3.0,
    "zipcode" : "63111",
    "students" : [ 
        {
            "name" : "jimi",
            "school" : 100.0,
            "age" : 8.0
        }, 
        {
            "name" : "messi",
            "school" : 102.0,
            "age" : 7.0
        }
    ]
}
需求2的结果

结果明显不对,

_id等于2不是我们想要的结果

原来它是匹配嵌入文档中所有的文档,所以匹配不准确,这时候$elemMatch就出现了

$elemMatch

$elemMatch适合用在嵌入文档中的多条件查询中,不要用在单条件查询中,有点大材小用

我们用elemmatch来解决一下上边的例子

db.getCollection('article').find({students:{$elemMatch:{'age':7,'school':100}}})
#结果
/* 1 */
{
    "_id" : 2.0,
    "zipcode" : "63110",
    "students" : [ 
        {
            "name" : "ajax",
            "school" : 100.0,
            "age" : 7.0
        }, 
        {
            "name" : "achilles",
            "school" : 102.0,
            "age" : 8.0
        }
    ]
}

嵌入式文档的更新

使用位置操作符$访问数组中嵌套的字段

使用注意:如果匹配到数组中很多值的时候,$符只能更新匹配到的第一个数组中的值。举例(如果数据中有两个叫张三的人,我们按照张三查找更新的时候只能更新一个张三的数据)

操作公式:

db.collection.update(
   { <query selector> },
   { <update operator>: { "array.$.field" : value } } # array数据的名字
)

例子:

#题目要求:把该文档中的std=8的字典中的grade:改为100
{
  _id: 4,
  grades: [
     { grade: 80, mean: 75, std: 8 },
     { grade: 85, mean: 90, std: 5 },
     { grade: 90, mean: 85, std: 3 }
  ]
}

方法:

db.getCollection('test1').update(
{"_id":4,"grades.std":8},
{"$set":{"grades.$.grade":100}}
)

结果:

{
    "_id" : 4,
    "grades" : [ 
        {
            "grade" : 100.0,
            "mean" : 75,
            "std" : 8
        }, 
        {
            "grade" : 85,
            "mean" : 90,
            "std" : 5
        }, 
        {
            "grade" : 90,
            "mean" : 85,
            "std" : 3
        }
    ]
}

更新所有符合条件的数据

https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/index.html

 

posted on 2019-09-24 15:55  程序员一学徒  阅读(445)  评论(0)    收藏  举报