ids = 602bc4c1a7fe3222c48b4efc
email = anartoflijkjk67g6#gmail.com
const Order = await User.aggregate([
{ $match: { email } },
{ $unwind: '$orders' },
{ $set: { _id : ids, "orders.orderStatus": "Paid" } }
])
I get an error while trying to update
code: 40324
codeName: "Location40324"
name: "MongoError"
ok: 0
My DB JSON
{ 14:46:51
comments: [],
orders: [
{
_id: 602bc4c1a7fe3222c48b4efc,
shares: 111,
userName: '111',
orderCreationDate: 2021-02-16T13:12:33.176Z,
orderStatus: 'In Cart',
totalOrderValue: 555100
},{
_id: 0000000000000001,
shares: 111,
userName: '1112',
orderCreationDate: 2021-02-16T13:12:33.176Z,
orderStatus: 'In Cart',
totalOrderValue: 55500
}
],
tikTokAccounts: [],
tikTokVideos: [],
paymentCards: [],
_id: 602bc0e024e05b15ccb12bc6,
userName: 'frfrf',
email: 'anartoflijkjk67g6#gmail.com',
password: '$2b$10$NC5CXa3lXK4Cl1.W3c3nae.YrJvvhum//YSYskXkKKiDULeJdvZoO',
avatar: 'https://www.flaticon.com/svg/static/icons/svg/667/667378.svg',
status: 'USER',
moneyAmount: 0,
__v: 2
}
How to find an order by id of a user with a specific email, and replace his orderStatus with "Paid"?
How can I fix it?
I kind of did as in the documentation
if you have orders._id, with update() you can do what you want, so just try like this:
db.collection.update({
"orders._id": "602bc4c1a7fe3222c48b4efc",
"email": "anartoflijkjk67g6#gmail.com"
},
{
$set: {
"orders.$.totalOrderValue": 12345
}
})
mongoplayground
Related
[
{
_id: new ObjectId("63cc22dfe258792490ac0fb5"),
categoryName: 'Rental Equipment',
products: [
{
_id: new ObjectId("63ce9701ba256f972473cd6a"),
partName: 'product one'
partNumber: 'ym129150-35151'
},
{
_id: new ObjectId("63ce2221207c858d01a3c8ac"),
partName: 'product two',
partNumber: 'ym129150-35151',
}
]
},{
_id: new ObjectId("63cc22dfe258792490ac0fb5"),
categoryName: 'Engine Parts',
products: [
{
_id: new ObjectId("23ce9701ba156f972473cd3a"),
partName: 'product one'
partNumber: 'ym129150-35151'
},
{
_id: new ObjectId("73ce2221203c858d01a3c83b"),
partName: 'product two',
partNumber: 'ym129150-35151',
}
]
}
]
I want to find the specific array(products) of object which one is located in the products array. I tried to find out the array of object but it's return a whole collections of object where the products _id is located.
const product = db.collection.find({
products: {
$elemMatch: {
_id: "63ce9701ba256f972473cd6a",
},
},
});
I Want to find a specific object from the products array.
The output would be:
{
_id: new ObjectId("63ce9701ba256f972473cd6a"),
partName: 'product one'
partNumber: 'ym129150-35151'
}
Try using the aggregation framework:
db.collection.aggregate([
{
"$unwind": "$products"
},
{
"$match": {
"products._id": "63ce9701ba256f972473cd6a",
}
},
{
"$project": {
"_id": 0,
"products._id": 1,
"products.partName": 1,
"products.partNumber": 1,
}
},
{
"$replaceRoot": {
"newRoot": "$products"
}
}
])
Link to playground
I have this kind of collection named 'Message'
[
{
_id: new ObjectId("62641aea1fbe19349f8fba78"),
text: 'Hello',
user: new ObjectId("625b8f00e2464fb758263b4d"),
receiver: new ObjectId("62638d3e5bcd98e7e48ca1b7"),
createdAt: 2022-04-23T15:27:38.270Z,
updatedAt: 2022-04-23T15:27:38.270Z,
__v: 0
},
{
_id: new ObjectId("6264256fc0ee5093f8d994a0"),
text: 'Hi',
user: new ObjectId("62638f1495b841266161b032"),
receiver: new ObjectId("62638d3e5bcd98e7e48ca1b7"),
createdAt: 2022-04-23T16:12:31.155Z,
updatedAt: 2022-04-23T16:12:31.155Z,
__v: 0
},
{
_id: new ObjectId("62642dc05318104caabbdecc"),
text: 'Hi',
user: new ObjectId("625b8f00e2464fb758263b4d"),
receiver: new ObjectId("62638d3e5bcd98e7e48ca1b7"),
createdAt: 2022-04-23T16:48:00.416Z,
updatedAt: 2022-04-23T16:48:00.416Z,
__v: 0
}
]
here user is the sender and the other one receiver. If my user id is "myId",
I want to retrieve distinct combinations of user and receiver of my message objects which means with a condition of user == myID or receiver == myId.
Expected values.
[
{
user: new ObjectId("625b8f00e2464fb758263b4d"),
receiver: new ObjectId("62638d3e5bcd98e7e48ca1b7")
},
{
user: new ObjectId("62638f1495b841266161b032"),
receiver: new ObjectId("62638d3e5bcd98e7e48ca1b7")
}
]
So I'm new to MongoDB, is there any possible way to do that? or is there anything I have missed?
Welcome Sandeep Vithanage,
You can do something like this:
db.collection.aggregate([
{
$match: {
$or: [
{
user: myId
},
{
receiver: myId
}
]
}
},
{
$group: {
"_id": {
user: "$user",
receiver: "$receiver"
}
}
},
{
$replaceRoot: {
"newRoot": "$_id"
}
}
])
As you can see working on the playground.
This is an aggregation pipeline. The first step is to match the cases you asked for. The second one is to group them by combinations of users and receivers. The third one is just formatting.
using $match and $project like below:
await Model.aggregate([{
$match: {
$or: [
{user: 'myid'},
{receiver: 'myid'}
] }
},
$project: {user: 1, receiver: 1}
])
I am trying to query a list of documents where a userid DOES NOT exist inside an array of objects.
The database (documents) looks like this:
[
{
title: 'object 1',
description: 'description 1',
members: [
{ profile: { id: '123', ...}, data: {} },
{ profile: { id: 'abc', ...}, data: {} },
{ profile: { id: 'def', ...}, data: {} },
]
},
{
title: 'object 2',
description: 'description 3',
members: [
{ profile: { id: 'aaa', ...}, data: {} },
{ profile: { id: 'bbb', ...}, data: {} },
{ profile: { id: 'ccc', ...}, data: {} },
]
},
]
Given that my userid is 'aaa' I am trying to query all documents where I am NOT a member.
I can successfully query all documents where my userid exists using this code:
await this._repository.findManyByQuery(
{
members: {
$elemMatch: {
"profile.id": "aaa",
},
},
},
)
However I am looking to query all objects where my ID DOES NOT exist. I have tried using $ne however it still returns the documents where the user id exists
members: {
$elemMatch: {
"profile.id": { $ne: "aaa" },
},
},
I guess I am looking for the opposite of $elemMatch but for querying inside an arry
You can use $not to negate the $elemMatch like this:
await this._repository.findManyByQuery({
members: {
"$not": {
$elemMatch: {
"profile.id": "aaa"
}
}
}
})
Example here
I created the account and project schema. The project schema have projectCreatorId that is also same value of my _id of a account. The result that I want is if the app fetch all the project in the list I want also to get the information related to the projectCreatorId that can be found in accountModel.
projectController.js
export const getProjectList = async (req, res) => {
try {
projectModel
.aggregate([
{
$lookup: {
from: 'accountModel',
localField: 'projectCreatorId',
foreignField: '_id',
as: 'output',
},
},
])
.then((result) => console.log(result));
} catch (error) {
res.status(500).json({ msg: error.message });
}
};
Result:
[
{
_id: 6124f5d1b77aab39fc8db7ba,
lastOpened: { date: 2021-08-24T13:36:17.364Z },
projectCreatorId: 612630b5caec270758fcbc22,
projectName: 'Project One',
projectNotes: '',
startDate: 2021-08-24T13:31:20.050Z,
endDate: 2021-08-31T13:31:20.000Z,
whoCanEdit: 'Admin',
viewType: 'List',
lastUpdate: 2021-08-24T13:36:17.364Z,
createdAt: 2021-08-24T13:36:17.364Z,
__v: 0,
output: []
},
{
_id: 6124f71db77aab39fc8db7c5,
lastOpened: { date: 2021-08-24T13:41:49.957Z },
projectCreatorId: 610fa182093746447c9c399f,
projectName: 'Project Two',
projectNotes: '',
startDate: 2021-08-24T13:41:36.304Z,
endDate: 2021-08-30T13:41:36.000Z,
whoCanEdit: 'Everyone',
viewType: 'List',
lastUpdate: 2021-08-24T13:41:49.957Z,
createdAt: 2021-08-24T13:41:49.957Z,
__v: 0,
output: []
},
{
_id: 61252481b77aab39fc8db81c,
lastOpened: { date: 2021-08-24T16:55:29.378Z },
projectCreatorId: 610fa182093746447c9c399f,
projectName: 'Project Three',
projectNotes: '',
startDate: 2021-08-24T16:55:13.490Z,
endDate: 2021-08-31T16:55:13.000Z,
whoCanEdit: 'Everyone',
viewType: 'List',
lastUpdate: 2021-08-24T16:55:29.378Z,
createdAt: 2021-08-24T16:55:29.378Z,
__v: 0,
output: []
}
]
AccountModel
projectModel
You only need a $lookup into an aggregation stage like this:
$lookup to merge result comparing _id and projectCreatorId. It creates an array called result
Then get the first position of the result array.
And use $project to output only values you want.
db.account.aggregate([
{
"$lookup": {
"from": "project",
"localField": "_id",
"foreignField": "projectCreatorId",
"as": "result"
}
},
{
"$set": {
"result": {
"$arrayElemAt": [
"$result",
0
]
}
}
},
{
"$project": {
"_id":0,
"name": 1,
"projectName": "$result.projectName",
"projectCreatorId": "$result.projectCreatorId"
}
}
])
Example here
I am newbie in MEANJS and i have a problem i.e, there are collection called employee and have multiple documents with their boss field. Now i want get all employees with their lower level.
For example:-
1) {_id:ObjectId('587dcd3edca5f235f862fdfd'), name:'John'} //he doesn't have boss
2) {_id:ObjectId('587dcd3edca5f235f86dddew'), name: 'Jimmy', 'boss': ObjectId('587dcd3edca5f235f862fdfd')} //john is boss
3) {_id:ObjectId('587dcd3edca5f235f863ew'), name: 'David', 'boss': ObjectId('587dcd3edca5f235f86dddew')} //john,Jimmy are bosses
4) {_id:ObjectId('587dcd3edca5f235f86qwa'), name: 'Dyan', 'boss': ObjectId('587dcd3edca5f235f86dddew')} //john,Jimmy,David are bosses
5) {_id:ObjectId('587dcd3edca5f235f8ew32'), name:'Jack', 'boss': ObjectId('587dcd3edca5f235f862fdfd')} //john is boss
6) {_id:ObjectId('587dcd3edca5f2wsw23rlot'), name: 'Loren', 'boss':ObjectId('587dcd3edca5f235f8ew32')} //john,Jack is boss
If we take
Jonh then output will ['Jimmy','Jack','David','Dyan','Loren']
Jack then output will ['Loren']
Here is my try code:-
getBosses(user._id)
function getBosses(id){
User.find({boss:id})
.exec(function(err,users){
if(err)
return console.log(err);
//How handle here 'users' array
//for something getBosses call recursively
})
}
As far as I understood you need to find all subordinates of that people. I think the best way to do it is using $graphLookup.
db.bosses.insertMany([
{ _id: "587dcd3edca5f235f862fdfd", name: "John" },
{
_id: "587dcd3edca5f235f86dddew",
name: "Jimmy",
boss: "587dcd3edca5f235f862fdfd",
},
{
_id: "587dcd3edca5f235f863ew",
name: "David",
boss: "587dcd3edca5f235f86dddew",
},
{
_id: "587dcd3edca5f235f86qwa",
name: "Dyan",
boss: "587dcd3edca5f235f86dddew",
},
{
_id: "587dcd3edca5f235f8ew32",
name: "Jack",
boss: "587dcd3edca5f235f862fdfd",
},
{
_id: "587dcd3edca5f2wsw23rlot",
name: "Loren",
boss: "587dcd3edca5f235f8ew32",
},
]);
db.bosses.aggregate([
{
$graphLookup: {
from: "bosses",
startWith: "$_id",
connectFromField: "_id",
connectToField: "boss",
as: "subordinates",
},
},
{
$project: {
_id: false,
name: true,
subordinates: {
$reduce: {
input: "$subordinates",
initialValue: "",
in: { $concat: ["$$value", ", ", "$$this.name"] },
},
},
},
},
{
$project: {
name: true,
subordinates: { $substrBytes: ["$subordinates", 2, -1] },
},
},
]);
The result of the last one is:
[
{ name: 'John', subordinates: 'David, Dyan, Loren, Jack, Jimmy' },
{ name: 'Jimmy', subordinates: 'David, Dyan' },
{ name: 'David', subordinates: '' },
{ name: 'Dyan', subordinates: '' },
{ name: 'Jack', subordinates: 'Loren' },
{ name: 'Loren', subordinates: '' }
]
The most important thing is $graphLookup stage of the aggregate pipeline. Last two $project stages is just response formatting - return only name and subordinates as string field with comma separated names.
To get data for a specific person you can use $match stage before $graphLookup like that:
db.bosses.aggregate([
{ $match: { name: "John" } },
{
$graphLookup: ...