簡體   English   中英

試圖從嵌套的 MongoDB 數據庫中獲取數據?

[英]Trying to fetch data from Nested MongoDB Database?

我是 MongoDB 的初學者,遇到了一個我試圖從嵌套數組中獲取數據的地方,但是它需要很長時間,因為數據大約是 50K 數據,而且它也不是很准確的數據,下面是架構結構,請看一次 -

    {
    "_id": {
      "$oid": "6001df3312ac8b33c9d26b86"
    },
    "City": "Los Angeles",
    "State":"California",
    "Details": [
      {
        "Name": "Shawn",
        "age": "55",
        "Gender": "Male", 
        "profession": " A science teacher with STEM",
        "inDate": "2021-01-15 23:12:17",
        "Cars": [
          "BMW","Ford","Opel"
        ],
        "language": "English"
      },
      {
        "Name": "Nicole",
        "age": "21",
        "Gender": "Female", 
        "profession": "Law student",
        "inDate": "2021-01-16 13:45:00",
        "Cars": [
          "Opel"
        ],
        "language": "English"
      }
    ],
    "date": "2021-01-16"
  } 

在這里,我試圖用日期和 Details.Cars 過濾日期

db.getCollection('news').find({"Details.Cars":"BMW","date":"2021-01-16"}

它也返回其他沒有汽車的人的詳細信息 - 寶馬,只試圖顯示具有寶馬或特殊數組值和日期的人的詳細信息 -妮可rest不應該出現,但它沒有發生

任何幫助表示贊賞。 :)

一個常見的錯誤認為find({nested.array:value})將僅返回嵌套的 object 但實際上,此查詢返回整個 object ,其中包含具有所需值的嵌套 object。

該查詢返回數組Details.Cars中存在值BMW整個文檔。 所以, Nicole也回來了。

要解決這個問題:

要獲得與條件匹配的多個元素,您可以使用$unwind進行聚合階段,將不同的對象分成數組並按您想要的條件進行匹配。

db.collection.aggregate([
  {
    "$match": { "Details.Cars": "BMW", "date": "2021-01-26" }
  },
  {
    "$unwind": "$Details"
  },
  {
    "$match": { "Details.Cars": "BMW" }
  }
])

此查詢首先按條件匹配,以避免$unwind覆蓋所有集合。

然后$unwind獲取每個文檔並再次$match以僅獲取您想要的文檔。

這里的例子


要僅獲取一個元素(例如,如果您通過_id及其唯一元素進行匹配),您可以通過以下方式使用$elemMatch

db.collection.find({
  "Details.Cars": "BMW",
  "date": "2021-01-16"
},
{
  "Details": {
    "$elemMatch": {
      "Cars": "BMW"
    }
  }
})

這里的例子

您可以使用$elemenMatch進入查詢或投影階段。 此處此處的文檔

使用$elemMatch進行查詢的方式是這樣的:

db.collection.find({
  "Details": {
    "$elemMatch": {
      "Cars": "BMW"
    }
  },
  "date": "2021-01-16"
},
{
  "Details.$": 1
})

這里的例子

結果是一樣的。 在第二種情況下,您使用位置運算符返回,如文檔所述:

與數組上的查詢條件匹配的第一個元素。

也就是"Cars": "BMW"所在的第一個元素。

你可以選擇你想要的方式。

頂級字段上的$match和數組元素上的$filter的組合將滿足您的需求。

db.foo.aggregate([
    {$match: {"date":"2021-01-16"}}
    ,{$addFields: {"Details": {$filter: {
        input: "$Details",
        as: "zz",
        cond: { $in: ['BMW','$$zz.Cars'] }
        }}
    }}
    ,{$match: {$expr: { $gt:[{$size:"$Details"},0] } }}
]);

筆記:

  1. $unwind對於這里需要的東西來說過於昂貴,它可能意味着稍后“重新組裝”數據形狀。
  2. 我們在要添加的新字段( Details已經存在的地方使用$addFields 這實際上意味着“就地覆蓋”,並且是過濾數組時的常見習慣用法。
  3. 第二個$match將消除date匹配但在Details.Cars中沒有單個條目的文檔是BMW ,即數組已被過濾到零長度。 有時您想知道此信息,因此如果是這種情況,請不要添加最終的$match
  4. 我建議您考慮使用真實日期,即ISODate而不是字符串,以便您可以輕松利用 MongoDB 日期數學和日期格式化函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM