嵌入文档的类型
嵌入文档有两种
一种为字典形式:
"_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 } ] }
结果明显不对,
_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
浙公网安备 33010602011771号