MongoDB查詢內嵌文檔

有兩種方式可以查詢內嵌文檔

  • 查詢整個文檔

  • 針對鍵值對進行查詢

查詢整個文檔

  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" }
)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末途茫,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子溪食,更是在濱河造成了極大的恐慌囊卜,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件错沃,死亡現場離奇詭異边败,居然都是意外死亡,警方通過查閱死者的電腦和手機捎废,發(fā)現死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來致燥,“玉大人登疗,你說我怎么就攤上這事∠釉椋” “怎么了辐益?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脱吱。 經常有香客問我智政,道長,這世上最難降的妖魔是什么箱蝠? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任续捂,我火速辦了婚禮,結果婚禮上宦搬,老公的妹妹穿的比我還像新娘牙瓢。我一直安慰自己,他們只是感情好间校,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布矾克。 她就那樣靜靜地躺著,像睡著了一般憔足。 火紅的嫁衣襯著肌膚如雪胁附。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天滓彰,我揣著相機與錄音控妻,去河邊找鬼。 笑死揭绑,一個胖子當著我的面吹牛饼暑,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼弓叛,長吁一口氣:“原來是場噩夢啊……” “哼彰居!你這毒婦竟也來了?” 一聲冷哼從身側響起撰筷,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤陈惰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后毕籽,有當地人在樹林里發(fā)現了一具尸體抬闯,經...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年关筒,在試婚紗的時候發(fā)現自己被綠了溶握。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒸播,死狀恐怖睡榆,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情袍榆,我是刑警寧澤胀屿,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站包雀,受9級特大地震影響宿崭,放射性物質發(fā)生泄漏。R本人自食惡果不足惜才写,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一葡兑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赞草,春花似錦铁孵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至轰异,卻和暖如春岖沛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搭独。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工婴削, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牙肝。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓唉俗,卻偏偏與公主長得像嗤朴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子虫溜,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內容

  • 目錄 查詢操作 集合查詢方法 find() 查詢內嵌文檔 查詢操作符(內含 數組查詢) "$gt" 雹姊、"$gte"...
    彩虹之夢閱讀 1,015評論 0 1
  • 查詢數組很容易吱雏,對于數組,我們可以這樣理解:數組中每一個元素都是這個鍵值對鍵的一個有效值瘾境,如下面的例子:我們要查詢...
    yzc123446閱讀 507評論 0 1
  • 一 基本概念 MongoDB中數據的結構為:庫歧杏、集合、文檔 1 數據庫 多個集合可以組成數據庫迷守。MongoDb的單...
    周東波_db閱讀 2,374評論 0 4
  • MongoDB 這幾天編寫程序犬绒,發(fā)現如果沒有理論的支持,即使時間花的再多兑凿,效率也是不高的凯力,所以每天在編程之前都應該...
    ofelia_why閱讀 546評論 0 2
  • 主要是說明mongodb的數據查詢方法,本次不使用mongo shell來操作急膀,使用圖形化操作軟件Robo來執(zhí)行m...
    Spareribs閱讀 4,010評論 1 10