英文:
MongoDB remove outer brackets from result
问题
不确定为什么我无法实现这个... 我只想返回结果,不要外部括号,之前我做过,但是最后阶段的分组方式会导致与 $mergeObjects(错误:输入是数组)和 $concatArrays(输入是对象)一起使用时出现错误。
管道:
User.aggregate([
{
$match: {
_id: userId
}
},
{
$lookup: {
from: 'clients',
localField: "clients",
foreignField: "_id",
as: "Clients",
pipeline: [
{
$project: {
_id: 1,
fullName: "$fullName",
contracts: {$last: "$contracts"}
}
},
{
$project: {
_id: 1,
fullName: 1,
contracts: {
type: "$contracts.contType",
hours: "$contracts.contHours"
}
}
}
]
}
},
{
$lookup: {
from: "visits",
localField: "visits",
foreignField: "_id",
as: "Visits",
pipeline: [
{
$match: {
$and: [
{visitStart: {$gte: new Date(start)}},
{visitEnd: {$lte: new Date(end)}}
]
}
},
{
$project: {
_id: 1,
client: "$client",
hours: "$totalHours",
month: {
"$month": "$visitEnd"
},
year: {
"$year": "$visitEnd"
}
}
},
{
$project: {
_id: 1,
client: 1,
hours: 1,
date: {
$concat: [
{
$substr: [
"$year",
0,
4
]
},
"-",
{
$substr: [
"$month",
0,
2
]
}
]
}
}
},
{
$group: {
_id: {
date: "$date",
client: "$client"
},
hoursCount: {
$sum: "$hours"
}
}
},
{
$group: {
_id: "$_id.client",
hours: {
$push: {
date: "$_id.date",
count: "$hoursCount"
}
}
}
},
{
$project: {
_id: 0,
client: "$_id",
hours: {
$sortArray: {input: "$hours", sortBy: {date: 1}}
}
}
}
]
}
},
{
$project: {
_id: 0,
"Clients": 1,
"Visits": 1
}
},
{
$project: {
result: {
$map: {
input: "$Clients",
as: "client",
in: {
$mergeObjects: [
"$$client",
{
$arrayElemAt: [
{
$filter: {
input: "$Visits",
as: "visits",
cond: { $eq: ["$$visits.client", "$$client._id"]}
}
},
0
]
}
]
}
}
}
}
},
结果:
[
{
"result": [
{
"_id": "6205a8313fe12d6b4ec354c4",
"fullName": "Johnny Cochrane",
"contracts": {
"type": "Quarterly",
"hours": 120
},
"client": "6205a8313fe12d6b4ec354c4",
"hours": [
{
"date": "2023-4",
"count": 5.51
},
{
"date": "2023-5",
"count": 6
},
{
"date": "2023-6",
"count": 2
}
]
},
{
"_id": "6217c1b73fe12d6b4ec3550e",
"fullName": "Sheila Thompson",
"contracts": {
"type": "Quarterly",
"hours": 140
},
"client": "6217c1b73fe12d6b4ec3550e",
"hours": [
{
"date": "2023-4",
"count": 5.5
},
{
"date": "2023-5",
"count": 4
},
{
"date": "2023-6",
"count": 2
}
]
}
]
}
]
我尝试了各种选项,例如最终阶段类似于这样的选项,但似乎无法正确实现:
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
"$$ROOT",
"$result"
]
}
}
},
理想情况下,我只想得到实际的数据数组,如下所示:
[
{
"_id": "6205a8313fe12d6b4ec354c4",
"fullName": "Johnny Cochrane",
"contracts": {
"type": "Quarterly",
"hours": 120
},
"client": "6205a8313fe12d6b4ec354c4",
"hours": [
{
"date": "2023-4",
"count": 5.51
},
{
"date": "2023-5",
"count": 6
},
{
"date": "2023-6",
"count": 2
}
]
},
{
"_id": "6217c1b73fe12d6b4ec3550e",
"fullName": "Sheila Thompson",
"contracts": {
"type": "Quarterly",
"hours": 140
},
"client": "6217c1b73fe12d6b4ec3550e",
"hours": [
{
"date": "2023-4",
"count": 5.5
},
{
"date": "2023-5",
"count": 4
},
{
"date": "2023-6",
"count": 2
}
]
}
]
英文:
Not sure why I'm not getting this... I just want to return the results without the outer brackets, which I've done before fine, but the way my last stage is grouping, it sets up the results in a way that gives errors with $mergeObjects (error: input is an array) and $concatArrays (input is an object).
Pipeline:
User.aggregate([
{
$match: {
_id: userId
}
},
{
$lookup: {
from: 'clients',
localField: "clients",
foreignField: "_id",
as: "Clients",
pipeline: [
{
$project: {
_id: 1,
fullName: "$fullName",
contracts: {$last: "$contracts"}
}
},
{
$project: {
_id: 1,
fullName: 1,
contracts: {
type: "$contracts.contType",
hours: "$contracts.contHours"
}
}
}
]
}
},
{
$lookup: {
from: "visits",
localField: "visits",
foreignField: "_id",
as: "Visits",
pipeline: [
{
$match: {
$and: [
{visitStart: {$gte: new Date(start)}},
{visitEnd: {$lte: new Date(end)}}
]
}
},
{
$project: {
_id: 1,
client: "$client",
hours: "$totalHours",
month: {
"$month": "$visitEnd"
},
year: {
"$year": "$visitEnd"
}
}
},
{
$project: {
_id: 1,
client: 1,
hours: 1,
date: {
$concat: [
{
$substr: [
"$year",
0,
4
]
},
"-",
{
$substr: [
"$month",
0,
2
]
}
]
}
}
},
{
$group: {
_id: {
date: "$date",
client: "$client"
// hours: "$hours"
},
hoursCount: {
$sum: "$hours"
}
}
},
{
$group: {
_id: "$_id.client",
hours: {
$push: {
date: "$_id.date",
count: "$hoursCount"
}
}
}
},
{
$project: {
_id: 0,
client: "$_id",
hours: {
$sortArray: {input: "$hours", sortBy: {date: 1}}
}
}
}
]
}
},
{
$project: {
_id: 0,
"Clients": 1,
"Visits": 1
}
},
{
$project: {
result: {
$map: {
input: "$Clients",
as: "client",
in: {
$mergeObjects: [
"$$client",
{
$arrayElemAt: [
{
$filter: {
input: "$Visits",
as: "visits",
cond: { $eq: ["$$visits.client", "$$client._id"]}
}
},
0
]
}
]
}
}
}
}
},
Result:
[
{
"result": [
{
"_id": "6205a8313fe12d6b4ec354c4",
"fullName": "Johnny Cochrane",
"contracts": {
"type": "Quarterly",
"hours": 120
},
"client": "6205a8313fe12d6b4ec354c4",
"hours": [
{
"date": "2023-4",
"count": 5.51
},
{
"date": "2023-5",
"count": 6
},
{
"date": "2023-6",
"count": 2
}
]
},
{
"_id": "6217c1b73fe12d6b4ec3550e",
"fullName": "Sheila Thompson",
"contracts": {
"type": "Quarterly",
"hours": 140
},
"client": "6217c1b73fe12d6b4ec3550e",
"hours": [
{
"date": "2023-4",
"count": 5.5
},
{
"date": "2023-5",
"count": 4
},
{
"date": "2023-6",
"count": 2
}
]
}
]
}
]
I've tried various options around a final stage like this, but cannot seem to get it right:
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
"$$ROOT",
"$result"
]
}
}
},
Ideally I'd just have the actual data array like so:
[
{
"_id": "6205a8313fe12d6b4ec354c4",
"fullName": "Johnny Cochrane",
"contracts": {
"type": "Quarterly",
"hours": 120
},
"client": "6205a8313fe12d6b4ec354c4",
"hours": [
{
"date": "2023-4",
"count": 5.51
},
{
"date": "2023-5",
"count": 6
},
{
"date": "2023-6",
"count": 2
}
]
},
{
"_id": "6217c1b73fe12d6b4ec3550e",
"fullName": "Sheila Thompson",
"contracts": {
"type": "Quarterly",
"hours": 140
},
"client": "6217c1b73fe12d6b4ec3550e",
"hours": [
{
"date": "2023-4",
"count": 5.5
},
{
"date": "2023-5",
"count": 4
},
{
"date": "2023-6",
"count": 2
}
]
}
]
Thanks for any guidance.
答案1
得分: 0
不确定我没有理解的是什么,但需要执行 $unwind "$result"
- 将数组转换为对象,然后使用 $replaceRoot
。出于某种原因,我以为我已经这样做了...可能只是动作太快。
{
$unwind: "$result"
},
{
$replaceRoot: {
newRoot: "$result"
}
}
英文:
Not sure what I wasn't getting, but needed to $unwind "$result" - turned the array to object, then $replaceRoot. For some reason I had thought I did that... maybe just moving too fast.
{
$unwind: "$result"
},
{
$replaceRoot: {
newRoot: "$result"
}
}
答案2
得分: 0
.pop()
它。
let a = ["test"];
let b = a.pop();
console.log(b);
英文:
.pop()
it.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let a = ["test"];
let b = a.pop()
console.log(b)
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论