How to set result of query as array with mongoose/mongodb - mongodb

I need to set the result of a query as an array of an object being saved.
First I get the Items:
Item.find({...}, function...
which looks like that:
data =
[ { foo: [],
bar: true,
_id: 564f62b1659abdc22b9dd1da },
{ foo: [],
bar: true,
_id: 564f76b628bd4b62335bad7c } ]
Now I create an object which I want to save with the _ids of the query result as an "Item" ref array:
var itemholder = new Itemholder(req.body);
itemholder.items = ????
Itemholder has an array of "Item" refs called "items" which should look like this:
"items" : [ { "item" : ObjectId("564f62b1659abdc22b9dd1da"),
"_id" : ObjectId("564f54c4e9bbbbee230647a4") },
{ "item" : ObjectId("564f76b628bd4b62335bad7c"),
"_id" : ObjectId("564f67043f88a5b12d6c32ff") } ]
Thank you.

Found a way to do it (probably not the best):
Item.find(..., function(err, data){
if(err){
...
}else{
data = data.map(function(data) { return {'item': data._id}; });
sprint.items = data;
sprint.save(function(err2, data2){
...

Related

How to update an array, by inserting an element at the first position

I want to update a document by adding a new element at the first position, in an array.
What I'm actually doing :
val updateRequest = myCollection.findOneAndUpdate(and(equal("site_id", new ObjectId(siteId)),and(equal("image_name", imageName))),
addToSet("url_history", urlHistory))
The result :
{
"_id" : ObjectId("5e297ea0c7ede90a7ae7586e"),
"image_name" : "test.jpg",
"url_history" : [
{
"date" : ISODate("2020-02-08T10:43:47.127Z"),
"url" : "No image url"
},
{
"date" : ISODate("2020-02-11T10:43:47.127Z"),
"url" : "test.jpg"
}
]
}
The desired result :
{
"_id" : ObjectId("5e297ea0c7ede90a7ae7586e"),
"image_name" : "test.jpg",
"url_history" : [
{
"date" : ISODate("2020-02-11T10:43:47.127Z"),
"url" : "test.jpg"
},
{
"date" : ISODate("2020-02-08T10:43:47.127Z"),
"url" : "No image url"
}
]
}
Have you tried the "$position" operator? Take a look https://docs.mongodb.com/manual/reference/operator/update/position/
Using mongoose would be like this:
const schema = Schema({ nums: [Number] });
const Model = mongoose.model('Test', schema);
const doc = await Model.create({ nums: [3, 4] });
doc.nums.push(5); // Add 5 to the end of the array
await doc.save();
// You can also pass an object with `$each` as the
// first parameter to use MongoDB's `$position`
doc.nums.push({
$each: [1, 2],
$position: 0
});
doc.nums; // [1, 2, 3, 4, 5]
from mongoose docs
And do you really need to insert it in the first position? Maybe is a good idea to preserve the array order and when you fetch its values you can just order by the way you desire, what do you think about it?
I finally found a solution !
Here it is :
val updateRequest = myCollection.findOneAndUpdate(and(equal("site_id", new ObjectId(siteId)),and(equal("image_name", imageName))),
pushEach("url_history", PushOptions().position(0), urlHistory))
I used the PushOptions.
Hope it helps.
Source :
https://mongodb.github.io/mongo-scala-driver/2.6/scaladoc/org/mongodb/scala/model/Updates$.html

access id of a nested document in mongoose

I want to write a put method in express for a nested document in mongoose.
I cannot access the id for the nested document.
{ "_id" : ObjectId("5b8d1ecbb745685c31ad8603"),
"name" : "abc",
"email" : "abc#gmail.com",
"projectDetails" : [
{
"technologies" : [
"abc",
"abc"
],
"_id" : ObjectId("5b8d1ecbb745685c31ad8604"),
"projectName" : "abc",
"projectDescription" : "abc",
"manager" : "abc",
"mentor" : "abc"
}
],
"__v" : 0
}
I am trying to access the id ("5b8d1ecbb745685c31ad8604") so that I can update the projectName.
I cannot think of how to write a put method for the same. Please help! Thanks in advance!!
You can use model.findOne() and then save() th update the document instead of model.findOneAndUpdate().
var projectId = "5b8d1ecbb745685c31ad8604";
var newProjectName = "def";
model.findOne({'projectDetails._id': projectId}, (err, data) => {
if (data) {
data.projectDetails.forEach((project) => {
if (project._id == projectId) {
project.projectName = newProjectName;
}
});
data.save();
} else {
// throw error message
}
})
app.put('/api/project/:id',(request,response)=>{
const projectId = request.params.id;
const projectName = "test";
db.users.update({"projectDetails._id":projectId},{$set:{"projectDetails.$.projectName":projectName}},function(err,data){
if(data){
}else{
}
})})
Instead of forEach try above query

How to query MongoDb documents using the indices of embedded arrays

I am trying to learn how to use mongo queries to reach deep into a data tree. Specifically, I'm trying to remove the object below {"object": 'to remove'}
{
"_id" : ObjectId("7840f22736341b09154f7ebf"),
"username" : "nmay",
"fname" : "Nate",
"lname" : "May",
"data" : [
{
"monthNum" : 1,
"year" : 2016,
"days" : [
{
"date" : "2016-01-01T06:00:00.000Z",
"type1" : [],
"type2" : []
},
{
"date" : "2016-01-02T06:00:00.000Z",
"type1" : [
{"object": 'to remove'}
],
"type2" : []
}
]
}
]
}
so far I know how to query for the user _id, but I'm not sure how to remove the desired object using the indices in each array. In this example I want to remove data[0].days[1].type1[0]
Here is the query that I have so far:
app.delete('/user/:id/data/:monthIndex/days/:dayIndex/type1/:type1Index', function (req, res, next) {
var monthIndex = parseInt(req.params.monthIndex); // these console the value properly
var dayIndex = parseInt(req.params.dayIndex); // -1 is applied to the parameter to translate to array position
var type1Index = parseInt(req.params.type1Index);
db.users.update(
{ _id: mongojs.ObjectId(req.params.id) },
{ $pull: data.monthIndex.days.dayIndex.type1.type1Index }
);
}
It gives me the error
ReferenceError: data is not defined
Can someone demonstrate how I can pass this query my index parameters to remove the desired object?
Unfortunately, there is no way to remove an array element by its numerical index with a single operation in MongoDB. In order to do this, you need to unset desired element(s) first, and remove the resulting null-valued fields afterwards.
Your code should look something like this:
db.users.update(
{ _id : mongojs.ObjectId(req.params.id) },
{ $unset : { 'data.0.days.1.type1.0' : 1 } }
);
db.users.update(
{ _id : mongojs.ObjectId(req.params.id) },
{ $pull : { 'data.0.days.1.type1' : null } }
);
Edit by #bob: to pass in the parameters you have to build the query string, which is ugly:
var unset = {};
unset['$unset'] = {};
unset.$unset['data.' + req.params.monthIndex + '.days.' + req.params.dayIndex + '.foods.' + req.params.foodIndex] = 1;
db.users.update( { _id : mongojs.ObjectId(req.params.id) }, unset );
var pull = {};
pull['$pull'] = {};
pull.$pull['data.' + req.params.monthIndex + '.days.' + req.params.dayIndex + '.foods'] = null;
db.users.update( { _id : mongojs.ObjectId(req.params.id) }, pull );

How to add key-value pair to object in MongoDB

If I have a document with the following basic structure:
{
...
Monday: { a:1, b:2 },
Tuesday: { c:3, d:4 }
...
}
Am I able to 'push' an additional key:value pair to Monday's value? Result would be:
{
Monday: { a:1, b:2, z:8 },
Tuesday: { c:3, d:4 }
...
}
The $push operator seems to only work for arrays.
Just do something like that
db.foo.update({"_id" :ObjectId("...") },{$set : {"Monday.z":8}})
How to add a new key:value pair to all existing objects of a mongoDB documents
Old Key and Value Pairs
> db.students.find().pretty();
{ "_id" : ObjectId("601594f5a22527655335415c"), "name" : "Doddanna" }
{ "_id" : ObjectId("601594f5a22527655335415d"), "name" : "Chawan" }
Update New Key and Value Pairs Using updateMany() and $set
> db.students.updateMany({},{$set:{newKey1:"newValue1", newKey2:"newValue2", newKeyN:"newValueN"}});
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }
Have a look on Updated pretty result
> db.students.find().pretty();
{
"_id" : ObjectId("601594f5a22527655335415c"),
"name" : "Doddanna",
"newKey1" : "newValue1",
"newKey2" : "newValue2",
"newKeyN" : "newValueN"
}
{
"_id" : ObjectId("601594f5a22527655335415d"),
"name" : "Chawan",
"newKey1" : "newValue1",
"newKey2" : "newValue2",
"newKeyN" : "newValueN"
}
I know this might be irrelevant to the question but as a matter of fact, I opened this page because I was looking for an exact query with mongoose. here is my answer with mongoose.
If we have an abstract model (mongoose schema) named week in our javascript application then the code will be:
// javascript with mongoose
...
const key = "z";
const KeyValue = 8;
await week.updateOne({
_id, // mongoDb document id
},
{
$set:{
[`Monday.${key}`]: KeyValue,
},
},
{
upsert: true // options
},
);
...
var json = {
Monday: { a:1, b:2 },
Tuesday: { c:3, d:4 } }
json['Monday']['z'] = 8;
console.log(json);

How do I add an array of elements in MongoDB to an array in an existing document?

In MongoDB, I'm trying to write a query to add elements from an array to an existing document, but instead of adding the elements as objects:
property: ObjectID(xxx)
the elements are getting added as just
ObjectID(xxx)
Forgive me if I get the terminology wrong. I'm completely new to MongoDB; I normally only work with relational databases. How do I properly add these new elements?
I have a collection called auctions which has two fields: ID and properties. Properties is an array of objects named property. Here's an example with two auction documents:
** I changed the object IDs to make them easier to reference in our discussion
Collection db.auctions
{
"_id" : ObjectId("abc"),
"properties" : [
{
"property" : ObjectId("prop1")
},
{
"property" : ObjectId("prop2")
},
{
"property" : ObjectId("prop3")
}]
}
{
"_id" : ObjectId("def"),
"properties" : [
{
"property" : ObjectId("prop97")
},
{
"property" : ObjectId("prop98")
}]
}
I want to add 3 new properties to auction "abc". How do I do this?
Here's is what I tried:
I have an array of properties that looks like this:
Array PropsToAdd
[
ObjectId("prop4"),
ObjectId("prop5"),
ObjectId("prop6")
]
I wrote an update query to push these properties into the properties array in auctions:
db.auctions.update(
{"_id": "abc"}
,
{ $push: { properties: { $each: PropsToAdd } } }
);
This query gave the result below. Notice that instead of adding elements named property with a value from my array, it's just added my values from my array. I obviously need to add that "property" part, but how do I do that?
Collection db.auctions (_id "abc" only)
{
"_id" : ObjectId("abc"),
"properties" : [
{
"property" : ObjectId("prop1")
},
{
"property" : ObjectId("prop2")
},
{
"property" : ObjectId("prop3")
},
ObjectId("prop4"),
ObjectId("prop5"),
ObjectId("prop6"),
ObjectId("prop7")]
}
The result I'm looking for is this:
Collection db.auctions (_id "abc" only)
{
"_id" : ObjectId("abc"),
"properties" : [
{
"property" : ObjectId("prop1")
},
{
"property" : ObjectId("prop2")
},
{
"property" : ObjectId("prop3")
},
{
"property" : ObjectId("prop4")
},
{
"property" : ObjectId("prop5")
},
{
"property" : ObjectId("prop6")
}
}
Here is some further information on that array of properties I'm adding. I get it from running these queries. Perhaps one of them needs changed?
This query gets an array of current properties:
var oldActiveProperties = db.properties.distinct( "saleNumber", { "active": true, "auction": ObjectId("abc") } );
Then those results are used to find properties in the new file that weren't in the old file:
var PropsToAdd = db.newProperties.distinct(
"_id"
, { "saleNumber": { "$nin": oldActiveProperties }, "active": true}
);
The resulting array is what I need to add to the auctions collection.
Use the JavaScript's native map() method to map the array into an array of documents. The following shows this:
var PropsToAdd = db.newProperties.distinct("_id",
{ "saleNumber": { "$nin": oldActiveProperties }, "active": true}
).map(function (p) { return { property: p }; });
db.auctions.update(
{"_id": "abc"},
{ $push: { "properties": { "$each": PropsToAdd } } }
);