有兩種方式可以查詢內嵌文檔
查詢整個文檔
針對鍵值對進行查詢
查詢整個文檔
db.emp.insert({
"id":"A001",
"name":{
"first":"Carey",
"last":"Ickes"
},
"age":25
})
db.emp.find({"name" : { "first" : "Carey", "last" : "Ickes" }})
> db.emp.find()
{ "_id" : ObjectId("561720d7de256e5153080ea7"), "id" : "A001", "name" : { "first" : "Carey", "last" : "Ickes" }, "age" : 25 }
> bb = db.emp.findOne({ "_id" : ObjectId("561720d7de256e5153080ea7") })
{
"_id" : ObjectId("561720d7de256e5153080ea7"),
"id" : "A001",
"name" : {
"first" : "Carey",
"last" : "Ickes"
},
"age" : 25
}
> db.emp.find({"name" : { "first" : "Carey", "last" : "Ickes" }})
{ "_id" : ObjectId("561720d7de256e5153080ea7"), "id" : "A001", "name" : { "first" : "Carey", "last" : "Ickes" }, "age" : 25 }
> bb.name = { "first" : "Carey", "last" : "Ickes", "middle" : "Joe" }
{ "first" : "Carey", "last" : "Ickes", "middle" : "Joe" }
> db.emp.save(bb)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.emp.find({"name" : { "first" : "Carey", "last" : "Ickes" }})
這種查詢會去精確匹配整個內嵌文檔。如果其中name元素的子集發(fā)生變化,查詢條件不與整個內嵌文檔相匹配。
而且這種查詢,還與順序有關系。
鍵值對查詢
查詢文檔時,可以用"."來表示進入內嵌文檔
> db.emp.find({ "name.last" : "Ickes", "name.first" : "Carey" })
{ "_id" : ObjectId("561720d7de256e5153080ea7"), "id" : "A001", "name" : { "first" : "Carey", "last" : "Ickes", "middle" : "Joe" }, "age" : 25 }
現在嗤练,如果Ickes增加了更多的鍵,這個查詢依然會匹配他的姓跟名在讶。
數組里包含內嵌文檔的查詢
db.blog.insert({
"_id":"B001",
"title":"MongoDB查詢",
"comments":[
{
"name":"ickes",
"score":3,
"comment":"nice"
},
{
"name":"xl",
"score":4,
"comment":"nice"
},
{
"name":"eksliang",
"score":5,
"comment":"nice"
},
{
"name":"ickes",
"score":6,
"comment":"nice"
}
]
})
db.blog.insert({
"_id":"B002",
"title":"MySQL查詢",
"comments":[
{
"name":"MySQL-ickes",
"score":4,
"comment":"nice"
},
{
"name":"MySQL-xl",
"score":9,
"comment":"nice"
},
{
"name":"MySQL-eksliang",
"score":5,
"comment":"nice"
},
{
"name":"MySQL-ickes",
"score":6,
"comment":"nice"
}
]
})
# 以下兩種查詢都是精確匹配文檔煞抬,所以查詢不出結果
> db.blog.find({ "comments" : { "name": "ickes", "score" : { "$gt" : 5 } } })
> db.blog.find({ "comments" : { "name": "ickes", "score" : { "$gt" : 5 }, "comment":"nice" } })
#
查詢條件里面的鍵值對會解釋為AND,但是對于數組的內嵌文檔來說它會解釋為OR的關系构哺。也就是
說上面的解釋會拆解為 comments.name : ickes 或者 comments.score : { "$gt" : 5 }
> db.blog.find({ "comments.name" : "ickes", "comments.score" : { "$gt":5 } })
{ "_id" : "B001", "title" : "MongoDB查詢", "comments" : [ { "name" : "ickes", "score" : 3, "comment" : "nice" }, { "name" : "xl", "score" : 4, "comment" : "nice" }, { "name" : "eksliang", "score" : 5, "comment" : "nice" }, { "name" : "ickes", "score" : 6, "comment" : "nice" } ] }
查詢 "name" : "ickes", "score" : { "$gt" : 5 }
> db.blog.find({"comments" : { "$elemMatch" : { "name" : "ickes", "score" : { "$gt" : 5 } } }})
{ "_id" : "B001", "title" : "MongoDB查詢", "comments" : [ { "name" : "ickes", "score" : 3, "comment" : "nice" }, { "name" : "xl", "score" : 4, "comment" : "nice" }, { "name" : "eksliang", "score" : 5, "comment" : "nice" }, { "name" : "ickes", "score" : 6, "comment" : "nice" } ] }
查詢 "score" : { "$gt" : 5 }
> db.blog.find({"comments" : { "$elemMatch" : { "score" : { "$gt" : 5 } } }})
{ "_id" : "B001", "title" : "MongoDB查詢", "comments" : [ { "name" : "ickes", "score" : 3, "comment" : "nice" }, { "name" : "xl", "score" : 4, "comment" : "nice" }, { "name" : "eksliang", "score" : 5, "comment" : "nice" }, { "name" : "ickes", "score" : 6, "comment" : "nice" } ] }
{ "_id" : "B002", "title" : "MySQL查詢", "comments" : [ { "name" : "MySQL-ickes", "score" : 4, "comment" : "nice" }, { "name" : "MySQL-xl", "score" : 9, "comment" : "nice" }, { "name" : "MySQL-eksliang", "score" : 5, "comment" : "nice" }, { "name" : "MySQL-ickes", "score" : 6, "comment" : "nice" } ] }
返回與查詢條件相匹配的任意一個數組元素
> db.blog.find({
"comments" : {
"$elemMatch" : {
"name" : "ickes",
"score" : { "$gt" : 5 }
}
}
},
{
"comments.$" : 2
}
)
> { "_id" : "B001", "comments" : [ { "name" : "ickes", "score" : 6, "comment" : "nice" } ] }
> qq = db.blog.findOne({ "_id" : "B002" })
> qq.comments = [
{
"name" : "ickes",
"score" : 9,
"comment" : "nice"
},
{
"name" : "MySQL-xl",
"score" : 9,
"comment" : "nice"
},
{
"name" : "MySQL-eksliang",
"score" : 5,
"comment" : "nice"
},
{
"name" : "MySQL-ickes",
"score" : 6,
"comment" : "nice"
}
]
> db.blog.save(qq)
再次執(zhí)行
db.blog.find({
"comments" : {
"$elemMatch" : {
"name" : "ickes",
"score" : { "$gt" : 5 }
}
}
},
{
"comments.$" : 2
}
)
> db.blog.find({ "comments" : { "$elemMatch" : { "name" : "ickes", "score" : { "$gt" : 5 } } } }, { "comments.$" : 2 })
{ "_id" : "B001", "comments" : [ { "name" : "ickes", "score" : 6, "comment" : "nice" } ] }
{ "_id" : "B002", "comments" : [ { "name" : "ickes", "score" : 9, "comment" : "nice" } ] }
>
最后再執(zhí)行
db.blog.find({
"comments" : {
"$elemMatch" : {
"name" : "ickes",
"score" : { "$gt" : 5 }
}
}
},
{
"comments.$" : 1
}
)
{ "_id" : "B001", "comments" : [ { "name" : "ickes", "score" : 6, "comment" : "nice" } ] }
{ "_id" : "B002", "comments" : [ { "name" : "ickes", "score" : 9, "comment" : "nice" } ] }
注意只有一個查詢條件革答,就可以不使用$elemMatch
下面兩個查詢是等價的
db.blog.find({ "comments.score" : { "$gt" : 5 } })
db.blog.find({ "comments" : { "$elemMatch" : { "score" : { "$gt" : 6 } } } })
$elemMatch 的用法
- 元素匹配
db.nums.insert([{ "results" : [ 82, 85, 88 ] },{ "results" : [ 75, 88, 89 ] }])
查詢 80 <= x < 85 的數據战坤,數組中的任何一個元素都要
大于等于80并且小于等于85
> db.nums.find({ "results" : { "$elemMatch" : { "$gte" : 80, "$lt" : 85 } } })
{ "_id" : ObjectId("5617320ade256e5153080ea9"), "results" : [ 82, 85, 88 ] }
- 數組內嵌文檔
db.survey.insert([
{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] },
{ _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] },
{ _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
{ _id: 4, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] },
{ _id: 5, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] },
{ _id: 6, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
])
查詢 product 為 xyz,并且score 大于 8 的集合
> db.survey.find({ results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } })
{ "_id" : 3, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }
{ "_id" : 6, "results" : [ { "product" : "abc", "score" : 7 }, { "product" : "xyz", "score" : 8 } ] }
> db.survey.find({ results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } }, { "results.$" : 1 })
{ "_id" : 3, "results" : [ { "product" : "xyz", "score" : 8 } ] }
{ "_id" : 6, "results" : [ { "product" : "xyz", "score" : 8 } ] }
- 單一查詢條件
如果只有單一的查詢條件残拐,那么可以不用 $elemMatch
db.survey.find({
results: { $elemMatch: { product: "xyz" } }
})
等同于
db.survey.find(
{ "results.product": "xyz" }
)