[英]How to find array greater than document size in MongoDB
我有如下架構
[
{
id:"111"
tags:[222,333,444,555]
},
{
id: "222"
tags:[312,345,534]
},
{
id:"333"
tags:[111,222,333,444,555]
},
]
我想在聚合管道中找到標簽數組大小大於$match
返回的文檔大小的所有文檔,因此在上面的示例中。 文檔數為 3,所以我想返回所有標簽數組大小大於 3 的文檔
[
{
id:"111"
tags:[222,333,444,555]
},
{
id:"333"
tags:[111,222,333,444,555]
},
]
我正在使用聚合管道來處理其他信息,我被困在如何存儲文檔大小以便我可以找到所有大於文檔大小的標簽
下面是我正在使用的查詢,我想在聚合和一次調用中進行
.aggregate([
{
"$match":{
"ids":{
"$in":[
"111",
"222",
"333"
]
}
}
})]
Facet 幫你解決這個問題。
$facet
有助於對傳入的文檔進行分類。 我們使用totalDoc
計數的文件和allDocuments
用於獲取所有的文件$arrayElemAt
有助於從totalDoc
中獲取第一個對象,我們已經知道在totalDoc
應該只有一個對象。 因為我們分組的時候用的是_id:null
$unwind
有助於allDocuments
數組這是代碼
db.collection.aggregate([
{
$facet: {
totalDoc: [
{
$group: {
_id: null,
count: {
$sum: 1
}
}
}
],
allDocuments: [
{
$project: {
tags: 1
}
}
]
}
},
{
$addFields: {
totalDoc: {
"$arrayElemAt": [
"$totalDoc",
0
]
}
}
},
{
$unwind: "$allDocuments"
},
{
$addFields: {
sizeGtDoc: {
$gt: [
{
$size: "$allDocuments.tags"
},
"$totalDoc.count"
]
}
}
},
{
$match: {
sizeGtDoc: true
}
},
{
"$replaceRoot": {
"newRoot": "$allDocuments"
}
}
])
您可以使用$facet
來獲得兩個流,即一個帶有過濾文檔的流和使用$count
。 然后可以使用$filter
進一步聚合生成的流,如下所示以獲得所需的結果
db.getCollection('collection').aggregate([
{ '$facet': {
'counts': [
{ '$match': { 'id': { '$in': ['111', '222', '333'] } } },
{ '$count': "numberOfMatches" }
],
'docs': [
{ '$match': { 'id': { '$in': ['111', '222', '333'] } } },
]
} },
{ '$project': {
'result': {
'$filter': {
'input': '$docs',
'cond': {
'$gt': [
{ '$size': '$$this.tags' },
{ '$arrayElemAt': ['$counts.numberOfMatches', 0] }
]
}
}
}
} }
])
你可以試試,
$match
你的條件$group
by null 並創建文檔的root
數組並在 count 中獲取根文檔的count
$unwind
解構root
數組$match
tags
大小和count
大於或不使用$expr
表達式匹配$replaceRoot
替換root
對象db.collection.aggregate([
{ $match: { id: { $in: ["111", "222", "333"] } } },
{
$group: {
_id: null,
root: { $push: "$$ROOT" },
count: { $sum: 1 }
}
},
{ $unwind: "$root" },
{ $match: { $expr: { $gt: [{ $size: "$root.tags" }, "$count"] } } },
{ $replaceRoot: { newRoot: "$root" } }
])
第二種選擇:
$match
和$group
都與上面的查詢相同,$project
過濾根數組匹配條件,如果tags
大小和count
大於或不大於,這將返回過濾后的根數組$unwind
解構根數組$replaceRoot
將根對象替換為根db.collection.aggregate([
{ $match: { id: { $in: ["111", "222", "333"] } } },
{
$group: {
_id: null,
root: { $push: "$$ROOT" },
count: { $sum: 1 }
}
},
{
$project: {
root: {
$filter: {
input: "$root",
cond: { $gt: [{ $size: "$$this.tags" }, "$count"] }
}
}
}
},
{ $unwind: "$root" },
{ $replaceRoot: { newRoot: "$root" } }
])
如果需要,您可以跳過
$unwind
和$replaceRoot
階段,因為此查詢始終以根目錄返回一個文檔,因此您可以輕松訪問像這樣的result[0]['root']
,您可以節省 2 個階段的處理和執行時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.