$pull from array in document - javascript

I am trying to $pull from an array within a mongodb document.
The document has the structure:
{
"_id" : ObjectId("54ee62ef688b41ff072b934b"),
"pictures" : [
{
"url" : "...",
"_id" : ObjectId("54ee6303688b41ff072b934d")
},
{
"url" : "...",
"_id" : ObjectId("54ee6304688b41ff072b934e")
},
{
"url" : "",
"_id" : ObjectId("54ee6304688b41ff072b934f")
}
]
}
I tried the update object
var update = { $pull: { pictures: {$elemMatch: {_id:req.params.picid } } } }
db.activity.update({_id: new ObjectId(req.params.id)}, update)
which returns writeresult: 1, but the picture is never removed.
ps I am using node, hense the req.params.picid

The $pull operator acts as a query document in itself and is also considered against every element of the array so $elemMatch is not needed:
var update = {
"$pull": { "pictures": { "_id": new ObjectId(req.params.picid) } }
};
You also need to cast your "string" from request params to an ObjectId.

Related

Search for keywords in array and only get the matching elements in MongoDB using NodeJS

I have a collection asset and This is my Data
{
"_id" : ObjectId("5e71d235a3b5401685a058"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-55-Inch",
"installedAt" : ["lobby", "storeroom", "f105"],
}
{
"_id" : ObjectId("5e71d235a3b540168475d8"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-32-Inch",
"installedAt" : ["lobby", "f108"],
}
{
"_id" : ObjectId("5eb3d53a7e16dc70244d6578"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-68-Inch",
"installedAt" : ["tvroom", "f105"],
}
{
"_id" : ObjectId("5eb3d53a7e16dc7024474a12"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-22-Inch",
"installedAt" : ["tvroom"],
}
So for the above data my requirement is to search for keyword in installedAt and return all the elements that match the keyword which user provides.
For Example, if the user searches for f10 then we should search all the installedAt arrays in assests and return like below
"installedAt": ["f105","f108"]
And I have tried using $in for getting similar elements but it is not working as I have expected.
This is my query
var autoRecords =[];
key = [searchString];
key.forEach(function(opt){
autoRecords.push(new RegExp(opt,"i"));
});
Assets.find({ "installedAt" : {"$in" : autoRecords},"company": companyId},{"installedAt" : 1})
So for the above query when I try to send search text which is f10 the result is as below
[
{"installedAt":["lobby", "storeroom", "f105"],"_id":"5e71d235a3b5401685a058"},
{"installedAt":["lobby", "f108"],"_id":"5e71d235a3b540168475d8"},
{"installedAt":["tvroom", "f105"],"_id":"5eb3d53a7e16dc70244d6578"},
]
It is getting all elements in the installedAt array even if it finds one. So Can anyone help me in getting only matched elements in the array and try to obtain this format
"installedAt": ["f105","f108"]
You can use below aggregation
const data = await Assets.aggregate([
{ $match: { installedAt: { $regex: "f10", $options: "i" }}},
{ $unwind: "$installedAt" },
{ $match: { installedAt: { $regex: "f10", $options: "i" }}},
{ $group: {
_id: null,
data: { $addToSet: "$installedAt" }
}}
])
MongoPlayground

Mongodb: project to return the field in array of object without using unwind

I need get value of field without using $unwind
because $unwind and $group takes much longer time.
My document (looks like):
{
"_id" : ObjectId("512e28984815cbfcb21646a7"),
"providers" : [
{
"list" : [
{
"code" : "ATT",
"descr" : "Attending"
}
],
"Name" : "John Doe",
"prvdId" : "1"
},
{
"list" : [
{
"code" : "RFR",
"descr" : "Referring"
},
{
"code" : "TRT",
"descr" : "Treating"
}
],
"Name" : "Smith William",
"prvdId" : "2"
}
]
}
cond is if "code" : "TRT", than get "prvdId"
Expected result is
{"prvdId" : "2"}
Use $filter with $in to look for a match in nested array followed by $let with $arrayElemAt to output prvdId in 3.4.
db.col.aggregate([
{"$match":{"providers.list.code":"TRT"}},
{"$project":{
"_id":0,
"prvdId":{
"$let":{
"vars":{
"providersl":{
"$filter":{
"input":"$providers",
"as":"providerf",
"cond":{"$in":["TRT","$$providerf.list.code"]}
}
}
},
"in":{"$arrayElemAt":["$$providersl.prvdId",0]}
}
}
}}
])
According to above mentioned description as a solution expected result can be obtained by using $elemMatch operator used to search an array element into find operation.
db.collection.find({
providers: {
$elemMatch: {
list: {
$elemMatch: {
code: "TRT"
}
}
}
}
}, {
'providers.$.prvdId': 1
})

How to get element from collection in Meteor if it multi-dimensional array or object or both?

I have collection "groups". like this:
{
"_id" : "e9sc7ogDp8pwY2uSX",
"groupName" : "one",
"creator" : "KPi9JwvEohKJsFyL4",
"eventDate" : "",
"isEvent" : true,
"eventStatus" : "Event announced",
"user" : [
{
"id" : "xfaAjgcSpSeGdmBuv",
"username" : "1#gmail.com",
"email" : "1#gmail.com",
"order" : [ ],
"price" : [ ],
"confirm" : false,
"complete" : false,
"emailText" : ""
},
...
],
...
"buyingStatus" : false,
"emailTextConfirmOrder" : " With love, your Pizzaday!! "
}
How can I get a value of specific element? For example i need to get value of "Groups.user.confirm" of specific group and specific user.
I tried to do so in methods.js
'pizzaDay.user.confirm': function(thisGroupeId, thisUser){
return Groups.find({ _id: thisGroupeId },{"user": ""},{"id": thisUser}).confirm
},
but it returns nothing.
Even in mongo console I can get just users array using
db.groups.findOne({ _id: "e9sc7ogDp8pwY2uSX"},{"user": ""})
The whole code is github
http://github.com/sysstas/pizzaday2
Try the following query:-
db.groups.aggregate(
[
{
$match:
{
_id: thisGroupeId,
"user.id": thisUser
}
},
{
$project:
{
groupName : 1,
//Add other fields of `user` level, if want to project those as well.
user:
{
"$setDifference":
[{
"$map":
{
"input": "$user",
"as": "o",
"in":
{
$eq : ["$$o.id" , thisUser] //Updated here
}
}
},[false]
]
}
}
}
]);
The above query will give the object(s) matching the query in $match inside user array. Now you can access any field you want of that particular object.
'pizzaDay.user.confirm': function(){
return Groups.findOne({ _id: thisGroupeId }).user.confirm;
I resolved it using this:
Template.Pizzaday.helpers({
confirm: function(){
let isConfirm = Groups.findOne(
{_id: Session.get("idgroupe")}).user.filter(
function(v){
return v.id === Meteor.userId();
})[0].confirm;
return isConfirm;
},
});
But I still think that there is some much elegant way to do that.

Accessing single field from object in array

I'm using Meteor with MongoDB and can't seem to figure out how to access a single field from the objects in an object array.
My documents:
{
"_id" : "p6c4cSTb3cHWaJqpG",
"createdAt" : ISODate("2016-05-11T11:30:11.820Z"),
"username" : "admin",
"contacts" : [
{
"when" : ISODate("2016-05-11T11:30:32.350Z"),
"who" : "4YBufbE9PByJBkasy"
},
{
"when" : ISODate("2016-05-25T11:52:49.745Z"),
"who" : "z792kEEYbxyzyEAKp"
},
{
"when" : ISODate("2016-05-26T13:47:43.439Z"),
"who" : "4YBufbE9PByJBkasy"
},
{
"when" : ISODate("2016-05-26T13:48:22.828Z"),
"who" : "4YBufbE9PByJBkasy"
}
]
}
I want to check if a userId is in any of the objects, specifically in the who fields.
My Server-side code:
var me = Meteor.userId();
var findMe = Meteor.users.findOne(me);
if (_.include(findMe.contacts, {who: 4YBufbE9PByJBkasy})){
console.log("found in array");
}else{
console.log("Not found in array");
}
}
I have tried this several different ways, but came up with nothing.
When I console.log(findMe.contacts);, it returns the whole array like it should. but when I try to console.log(findMe.contacts.who);, it returns undefined.
Just need some direction on how to access the field of the object array. Thanks!
Looping through an array to see whether it contains a value is easily
done with Array.prototype.some:
var data = {
"_id" : "p6c4cSTb3cHWaJqpG",
"createdAt" : "2016-05-11T11:30:11.820Z",
"username" : "admin",
"contacts" : [
{
"when" : "2016-05-11T11:30:32.350Z",
"who" : "4YBufbE9PByJBkasy"
},
{
"when" : "2016-05-25T11:52:49.745Z",
"who" : "z792kEEYbxyzyEAKp"
},
{
"when" : "2016-05-26T13:47:43.439Z",
"who" : "4YBufbE9PByJBkasy"
},
{
"when" : "2016-05-26T13:48:22.828Z",
"who" : "4YBufbE9PByJBkasy"
}
]
};
var hascontact = function(contacts, id){
return contacts.some(function(contact){
return contact.who === id;
});
};
console.log(hascontact(data.contacts,'4YBufbE9PByJBkasy'));
console.log(hascontact(data.contacts,'z792kEEYbxyzyEAKp'));
console.log(hascontact(data.contacts,'asdfasdfasdfasdfa'));

How to delete deep array in mongodb?

I am trying to delete "virtualNumber" : "12345" in the following document:
{
"_id" : ObjectId("50a9db5bdc7a04df06000005"),
"billingInfo" : null,
"date" : "dsfdsfsdfsd",
"description" : "sdfsdff",
"pbx" : {
"_id" : ObjectId("50a9db5bdc7a04df06000006"),
"did" : {
"1234567890" : {
"inventoryId" : "509df7547e84b25e18000001",
"didcountry" : "india",
"didState" : "bangalore",
"routeType" : "CallForward",
"didNumber" : "1234567890",
"didVirtualNumbers" : [
{
"virtualNumber" : "12345"
},
{
"virtualNumber" : "56789"
}
],
"id" : ObjectId("50a9db9acdfb4f9217000002")
}
},
},
I am using node.js, so I constructed a query in JavaScript:
var query = {_id: ObjectId("50a9db5bdc7a04df06000005")};
var obj = {};
obj["pbx.did.1234567890.didVirtualNumbers.virtualNumber"]=12345;
//problem
collection.update(query,{$pull:obj});
You need to match the array element like:
{"$pull": {"pbx.did.7259591220.didVirtualNumbers": {"virtualNumber": "12345"}}}
So you should change your code to:
obj["pbx.did.7259591220.didVirtualNumbers"]={"virtualNumber": "12345"};
Please refer to http://www.mongodb.org/display/DOCS/Updating#Updating-%24pull
It mentions the pull field should be an array.

Categories