[英]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] } }}
]);
筆記:
$unwind
對於這里需要的東西來說過於昂貴,它可能意味着稍后“重新組裝”數據形狀。Details
)已經存在的地方使用$addFields
。 這實際上意味着“就地覆蓋”,並且是過濾數組時的常見習慣用法。$match
將消除date
匹配但在Details.Cars
中沒有單個條目的文檔是BMW
,即數組已被過濾到零長度。 有時您想知道此信息,因此如果是這種情況,請不要添加最終的$match
。ISODate
而不是字符串,以便您可以輕松利用 MongoDB 日期數學和日期格式化函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.