How to remove an Item from an Mongodb array documents - javascript

I have the following mongodb collection named Posts with document like following:
{
"_id" : "111",
"comments" : [
{
"replyPost" : "aaaa",
"username" : "John Doe"
},
{
"replyPost" : "bbbb",
"username" : "Jane Smith"
},
{
"replyPost" : "cccc",
"username" : "Jane Smith"
},
{
"replyPost" : "dddd",
"username" : "Jane Smith"
}
]
}
I am trying to remove an array item with the replyPost: "cccc" so the result would be:
{
"_id" : "111",
"comments" : [
{
"replyPost" : "aaaa",
"username" : "John Doe"
},
{
"replyPost" : "bbbb",
"username" : "Jane Smith"
},
{
"replyPost" : "dddd",
"username" : "Jane Smith"
}
]
}
I have tried .update method with $pull refering to mongodb document
https://docs.mongodb.com/manual/reference/operator/update/pull/
Posts.update(
{_id: this._id},
{ $pull: { comments: { replyPost:"cccc"} } }
);
which don't seem to be working. can anyone see the problem?

See if you're getting the right _id. It's in string format.
I tried the same in mongo shell. It worked for me.
Here's the log:
> db.posts.insert({
... "_id" : "111",
... "comments" : [
... {
... "replyPost" : "aaaa",
... "username" : "John Doe"
... },
... {
... "replyPost" : "bbbb",
... "username" : "Jane Smith"
... },
... {
... "replyPost" : "cccc",
... "username" : "Jane Smith"
... },
... {
... "replyPost" : "dddd",
... "username" : "Jane Smith"
... }
... ]
... })
WriteResult({ "nInserted" : 1 })
> db.posts.update({_id:'111'},{$pull:{comments:{replyPost:'cccc'}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.posts.findOne()
{
"_id" : "111",
"comments" : [
{
"replyPost" : "aaaa",
"username" : "John Doe"
},
{
"replyPost" : "bbbb",
"username" : "Jane Smith"
},
{
"replyPost" : "dddd",
"username" : "Jane Smith"
}
]
}

If you are using mongoose, you can do:
db.posts.remove({replyPost: 'cccc'}, function(err) {
})
The first parameter can be any mongoose query expression. All matches will be removed from db.
See mongoose remove

Tested Works Fine:
Posts.update((
{"_id" : "111"},
{ $pull: {comments: {"replyPost" : "cccc"}} },
{ multi: true }
)

Related

MongoDB trying to marge two tables by id - cant make this

I have two tables in my database.
teams table:
[
{
"users": [
{ "id": '5f9971e6f4f60959c0668896', "role": 'admin' },
{ "id": '5fb11570ece5672ba95850ee', "role": 'read' }
],
"_id": '5fb0f993795d1634d4e486dc',
"name": 'team1'
},
{
"users": [
{ "id": '5fb11570ece5672ba95850ee', "role": 'admin' }
],
"_id": "5fb0f993795d1634d4e48fed",
"name": 'team2'
}
]
users table:
[
{
"_id" : ObjectId("5f9971e6f4f60959c0668896"),
"firstname" : "foo",
"lastname" : "bar"
},
{
"_id" : ObjectId("5fb11570ece5672ba95850ee"),
"firstname" : "hey",
"lastname" : "you"
},
{
"_id" : ObjectId("5fb11570ece5672ba95grs0"),
"firstname" : "12",
"lastname" : "34"
}
]
and what i want to get is this:
{
users:
[
{ id: '5f9971e6f4f60959c0668896',firstname: "foo",lastname: "bar", role: 'admin' },
{ id: '5fb11570ece5672ba95850ee',firstname: "hey",lastname: "you", role: 'read' }
],
_id: 5fb0f993795d1634d4e486dc,
name: 'team1'
}
i'm trying to solve this a week and i didn't find solution.
Teams.aggregate([
{
$lookup: {
from: "users",
localField: "_id",
foreignField: "users.id",
as: "users",
},
},
]).then((data) => {
console.log("data", data);
});
tnx for the help
Your teams collection users.id need to be also ObjectId , not a string ... , or alternatively you need to change the users collection _id's to strings ...

How to Join 2 Collection into 1 in Mongoose without Populate

so I have the task to combine 2 collections into 1 to be able to search by additional parameter queries
like ac_key or ac_value,
but the reality is not as expected, this only works for one collection, when I do a search with the other collection nothing happens
account collection
{
"_id" : ObjectId("5ce2409399c7952d4c6f0f5d"),
"status" : "not verified",
"name" : "Monkey D Garp",
"phone" : "1234",
"email" : "ccc#ccc.com",
"password" : "$2a$10$186wQau8GBtqOORovWP7..r8bwSAW1kK9Cb0lT8ckeNFSkEDYjOuu"
},
{
"_id" : ObjectId("5ce2408b99c7952d4c6f0f5b"),
"status" : "not verified",
"name" : "Monkey D Garp",
"phone" : "1234",
"email" : "aaa#aaa.com",
"password" : "$2a$10$WskmjNldC2TQ13Rl6ZLqROJwIux1KwM2tkCqfbiMSxWKRUAgsQWn."
},
{
"_id" : ObjectId("5ce2407c99c7952d4c6f0f59"),
"status" : "not verified",
"name" : "Monkey D Garp",
"phone" : "1234",
"email" : "bbb#bbb.com",
"password" : "$2a$10$g1WRwu4Tp85hIIyw4ONd9e3CGOd7u8UN1jfF.zsVpAOE9Usdy01Bm"
}
account_meta collection
{
"_id" : ObjectId("5ce37884551b0b07f4b60598"),
"value" : "sleeping",
"key" : "speciality",
"account_id" : ObjectId("5ce2407c99c7952d4c6f0f59")
},
{
"_id" : ObjectId("5ce240fc99c7952d4c6f0f61"),
"value" : "cooking",
"key" : "hobby",
"account_id" : ObjectId("5ce2407c99c7952d4c6f0f59")
},
{
"_id" : ObjectId("5ce240f399c7952d4c6f0f60"),
"value" : "12",
"key" : "age",
"account_id" : ObjectId("5ce2407c99c7952d4c6f0f59")
},
{
"_id" : ObjectId("5ce240e799c7952d4c6f0f5f"),
"value" : "singapore",
"key" : "address",
"account_id" : ObjectId("5ce2407c99c7952d4c6f0f59")
},
{
"_id" : ObjectId("5ce2409399c7952d4c6f0f5e"),
"value" : "staff",
"account_id" : ObjectId("5ce2409399c7952d4c6f0f5d"),
"key" : "role"
},
{
"_id" : ObjectId("5ce2408b99c7952d4c6f0f5c"),
"value" : "user",
"account_id" : ObjectId("5ce2408b99c7952d4c6f0f5b"),
"key" : "role"
},
{
"_id" : ObjectId("5ce2407c99c7952d4c6f0f5a"),
"value" : "admin",
"account_id" : ObjectId("5ce2407c99c7952d4c6f0f59"),
"key" : "role"
}
expected output
[{
"status": "not verified",
"_id": "5ce2407c99c7952d4c6f0f59",
"name": "Monkey D Garp",
"phone": "1234",
"email": "bbb#bbb.com",
"password": "$2a$10$g1WRwu4Tp85hIIyw4ONd9e3CGOd7u8UN1jfF.zsVpAOE9Usdy01Bm",
"role": "admin",
"address": "singapore",
"age": "12",
"hobby": "cooking",
"speciality": "sleeping"
}]
the condition: I want to find the key and value with the parameters ac_key and ac_value, when I look for non-specific and related data it will not appear, and get all the meta related to the same account_id
assuming data to merge from account to meta account exists _id (account) = account_id (account_meta)
in reality when i hit ac_key: age, and ac_value: '12', i get:
[
{
"status": "not verified",
"_id": "5ce2407c99c7952d4c6f0f59",
"name": "Monkey D Garp",
"phone": "1234",
"email": "bbb#bbb.com",
"password": "$2a$10$g1WRwu4Tp85hIIyw4ONd9e3CGOd7u8UN1jfF.zsVpAOE9Usdy01Bm",
"role": "admin",
"address": "singapore",
"age": "12",
"hobby": "cooking",
"speciality": "sleeping"
},
{
"status": "not verified",
"_id": "5ce2408b99c7952d4c6f0f5b",
"name": "Monkey D Garp",
"phone": "1234",
"email": "aaa#aaa.com",
"password": "$2a$10$WskmjNldC2TQ13Rl6ZLqROJwIux1KwM2tkCqfbiMSxWKRUAgsQWn.",
"role": "user"
},
{
"status": "not verified",
"_id": "5ce2409399c7952d4c6f0f5d",
"name": "Monkey D Garp",
"phone": "1234",
"email": "ccc#ccc.com",
"password": "$2a$10$186wQau8GBtqOORovWP7..r8bwSAW1kK9Cb0lT8ckeNFSkEDYjOuu",
"role": "staff"
}
]
this is my controller
exports.get_Account = async (req, res) => {
const { _id, name, email, phone, status, ac_key, ac_value } = req.query
const accounts = await Account.find({
// query database query
...(_id && {_id : { $in : _id.split(",") }}),
...(name && {$text : { $search: name }}),
...(email && {email : { $in : email.split(",") }}),
...(phone && {phone : { $in : phone.split(",") }}),
...(status && {status : { $in : status.split(",") }}),
});
const newAcc = await accounts.map(async account => {
const accMeta = await AccountMeta.find({
...({account_id : account._id}),
...(ac_key && {key : ac_key}),
...(ac_value && {value : ac_value})
});
console.log('accMeta', accMeta)
const new_account = {};
await accMeta.map(editMeta => {
new_account[editMeta.key] = editMeta.value;
});
let dynamicAccount = Object.assign({}, account._doc, new_account); //cuma
return {...dynamicAccount}
});
await Promise.all(newAcc).then(result => res.status(200).json(result))
};
thanks in advance

Join two collection in mongoDB and extract out data in node js

I am using MongoDB 3.6 for my project.
I have 2 collections "users" and "follow". I want to extract out details of user's followers and following (like an Instagram app).
users collection
{
"id" : "1",
"name" : "abc",
"age" : "26"
},
{
"id" : "2",
"name" : "xyz",
"age" : "22"
},
{
"id" : "3",
"name" : "qwe",
"age" : "23"
}
follow collection
{
"id" : "2",
"follow id" : "1"
},
{
"id" : "3",
"follow id" : "1"
},
{
"id" : "1",
"follow id" : "2"
},
{
"id" : "2",
"follow id" : "3"
},
{
"id" : "1",
"follow id" : "3"
}
Now i want following list of id 2 So id 2 is following id 1 and id 3
So, Output should be like this
{
"id" : "1",
"name" : "abc",
"age" : "26"
},
{
"id" : "3",
"name" : "qwe",
"age" : "23"
}
For that, I am using $lookup aggregation. But this is not giving the desired output which I want.
Here is my code -
Follow.aggregate([
{
$lookup:{
from:"users",
localField:"id",
foreignField:"id",
as:"fromItems"
}
},
{
$replaceRoot:{newRoot: {$mergeObjects: [ { $arrayElemAt: ["$fromItems", 0 ] }, "$$ROOT" ] } }
},
{ $project :
{
fromItems : 0
}
}
], callback)
For more understanding please refer the image
To get following list of id 2 you can use following query:
Follow.aggregate([
{
$match: { "id": "2" }
},
{
$lookup:{
from:"users",
localField:"follow id",
foreignField:"id",
as:"fromItems"
}
},
{
$replaceRoot:{newRoot: {$mergeObjects: [ { $arrayElemAt: ["$fromItems", 0 ] }, "$$ROOT" ] } }
},
{ $project :
{
id : "$follow id",
name: 1,
age: 1
}
}
])
So the point here is that you have a relation between id and follow id and after $lookup phase follow id becomes the new id since it's parent-child relation.
EDIT:
3.4 solution below
Follow.aggregate([
{
$match: { "id": "2" }
},
{
$lookup:{
from:"users",
localField:"follow id",
foreignField:"id",
as:"fromItems"
}
},
{
$project: {
id: "$follow id",
from: { $arrayElemAt: ["$fromItems", 0 ] }
}
},
{ $project :
{
id : 1,
name: "$from.name",
age: "$from.age"
}
}
])

JS Object Array Remove last empty element

I have that javascript object :
MyObject = [
{
"name" : "aaa",
"firstname" : "aaaaa"
},
{
"name" : "bbb",
"firstname" : "bbbb"
},
{
"name" : "cccc",
"firstname" : "" <--------- firstname is empty, but the element is not in the last
},
{
"name" : "ddd",
"firstname" : "dddd"
},
{
"name" : "eeee",
"firstname" : "" <--------- firstname is empty
},
{
"name" : "fffff",
"firstname" : "" <--------- firstname is empty
},
]
I want to delete the lastest lines that have "firstname" empty ... (a sort of trim) ... i dont want to remove all lines that have "firstname" empty... but just who are in the latestes lines. (that are in the bottom)
So, the result will be :
MyObject = [
{
"name" : "aaa",
"firstname" : "aaaaa"
},
{
"name" : "bbb",
"firstname" : "bbbb"
},
{
"name" : "cccc",
"firstname" : ""
},
{
"name" : "ddd",
"firstname" : "dddd"
}
]
Thank you
You can pop of at the end of the array as long as the firstname is empty
var MyObject = [{
"name": "aaa",
"firstname": "aaaaa"
}, {
"name": "bbb",
"firstname": "bbbb"
}, {
"name": "cccc",
"firstname": ""
}, {
"name": "ddd",
"firstname": "dddd"
}, {
"name": "eeee",
"firstname": ""
}, {
"name": "fffff",
"firstname": ""
}];
for (var i=MyObject.length;i--;) if (MyObject[i].firstname==="") MyObject.pop(); else break;
console.log(MyObject)
.as-console-wrapper {max-height: 100%!important; top: 0!important;}
Try this:
var MyObject = [
{
"name" : "aaa",
"firstname" : "aaaaa"
},
{
"name" : "bbb",
"firstname" : "bbbb"
},
{
"name" : "cccc",
"firstname" : ""
},
{
"name" : "ddd",
"firstname" : "dddd"
},
{
"name" : "eeee",
"firstname" : ""
},
{
"name" : "fffff",
"firstname" : ""
}
];
var i = MyObject.length;
while(true) {
if (!MyObject[--i].firstname) {
MyObject.pop();
} else {
break;
}
}
console.log(MyObject);

insert in subdocument with mongoDB

I have the following document in the collection:
"_id" : "2",
"workspace" : [{
"name" : "1",
"widgets" : [ ]
},{
"name" : "2",
"widgets" : [ ]
},{
"name" : "3",
"widgets" : [ ]
},{
"name" : "4",
"widgets" : [ ]
}
]}
How can I insert {id: "1", blabla: "blabla"} in "widgets" for the "name" 3?
In comparison to a previous answer which just inserts everything into the root of the document, here is a correct way to do this with positional operator:
db.t.update({
"_id" : "2",
"workspace.name" : "3"
},{
$push: {
'workspace.$.widgets' : {
id: "2",
blabla: "blabla"
}
}
});

Categories

Resources