I have a Mongoose schema with, among other things, an array of objects like so:
multipleThings: [{
field1: String,
field2: String,
field3: String,
thingId : { type: ObjectId, default: ObjectId }
}]
In my code I do a .findOne, which returns my object. myObject.multipleThings is an Array[0] at this point. I simply want to push something to this array, so I do
myObject.multipleThings.push(anObjectICreated)
And I get
undefined is not a function
at DocumentArray.SchemaType.applySetters (.../node_modules/mongoose/lib/schematype.js:570:26)
at Array.MongooseArray.mixin.push (.../node_modules/mongoose/lib/types/array.js:292:27)
at {The location of .push above in my code}
I don't understand what is stopping me from being able to push to the array?
I am still new to this as well put may I suggest you try myObject.multipleThings[0].push(anObjectICreated)
Related
I'm being in a case in which I don't know why or what causes it. I can't find any info on this weird problem. So I'm gonna ask here.
//mongoDB data schema
const dataSchema = mongoose.Schema({
userID: String,
userStocks: Array,
stockMarket: Array,
});
module.exports = mongoose.model('Data', dataSchema);
The problem then arrives when creating a new collection in the database:
var regUser = new Data({
});
console.log(regUser); return;
The console.log(regUser) returns both the stockMarket array and userStock array as empty arrays.
Why is this? And how do I prevent it?
It works fine with Number and String type. But with Array type it seems to auto insert it for some reason.
I've tried with delete regUser.stockMarket but it does nothing despite returning true when run. I've also tried removing them with an aggregate using $unset and $merge but still nothing.
So does anyone have any idea what could be causing this weird case? And how would I fix it?
-----------EDIT-----------
Based on the answer from #HuyPham I found out the problem was that I didn't correctly declare it as in array in the schema constructor. The correct way of doing it was:
const dataSchema = mongoose.Schema({
userID: String,
userstocks: {
type: Array,
default: undefined
},
stockMarket: {
type: Array,
default: undefined
}
});
You have defined Array type in mongoose.Schema in the wrong way. Take a look at Arrays in mongoose docs. In case you receive empty array for userStocks and stockMarket maybe it's take Array instance as default value.
In the correct way you found above, make an adjustment from type: Array to type:[] to prevent unpredictable issues when using JavaScript Array instance to set type.
const dataSchema = mongoose.Schema({
userID: String,
userstocks: {
type: [],
default: undefined
},
stockMarket: {
type: [],
default: undefined
}
});
I've been trying to update a particular object in a Mongodb document without any luck using the findOneAndUpdate() method. This is what my collectiom looks like
{
_id: new ObjectId("61da0ab855483312e8f4483b"),
products: [
{
createdAt: 2022-01-08T22:05:44.635Z,
_id: new ObjectId("61da0ab855483312e8f4483c"),
productCode: 'otf',
productName: 'facebookmeta',
claims: [Array],
permissions: []
},
{
createdAt: 2022-01-08T22:05:44.635Z,
_id: new ObjectId("61da0ab855483312e8f4483f"),
productCode: '4pf',
productName: 'twitteroauth',
claims: [Array],
permissions: [Array]
}
],
__v: 0
}
When i try something like this. i am trying to find a singular object based on its product code and update that object
ProductModel.findOneAndUpdate({productCode: userData.productCode}, dataToBeUpdated, {new: true})
it returns a
Performing an update on the path '_id' would modify the immutable field '_id
i am suspecting that MongoDB is applying query conditions on collection and returns the result with the matching documents so its probably returning both objects which is probably the cause of the error i am encountering but i could be wrong.
How can i efficiently point it to the right object and perform an update
MongoDB supports the single-level deep update of subdocument using positional operator ($).
db.collection_name.update({
_id: ObjectId("61da0ab855483312e8f4483b"),
"products.productCode": "4pf"
},
{
"$set": {
"products.$.productName": "twitteroauth name updated"
}
})
In the above update clause, $ will be replaced by the matching index of a subdocument at a runtime.
For example $ will be replaced by value 1 at a runtime because of "products.productCode": "4pf" condition
Please note the below points:
You must include the array field as part of the query document.
The positional operator cannot be used for updates inside of a nested array.
Additional Reference: https://docs.mongodb.com/manual/reference/operator/update/positional/
I 'm facing an issue while trying to get some results from a mongoDB aggregation pipeline.
Here's what my DB look like:
var dbSchema = mongoose.Schema({
identity: Number,
parametres: {
style: {
fuel: [styleSchema],
gasoline: [styleSchema],
},
},
And here's what the styleSchema looks like:
var styleSchema = new mongoose.Schema({
date: Date,
value: Number,
type: String,
});
I'm trying to extract ALL the objects in 'fuel' and 'gasoline' which are of some kind of 'type'.
I've tried to group both in a unique array with concatArray and then match the 'type' I want by:
db.aggregate([
{$match:
{'identity':3,
}},
{$project: {all: {$concatArrays: ['$parametres.style.fuel','$parametres.style.gasoline']} }},
{$match: {'$all.type': 'example'}},
Before trying to match the second time, I've got a unique array ('all') and I try to match some things on it, but nothing works (I've tried 'all.type' also)...
I've probably misunderstood the way I have to use the 'match' query as I am a beginner, so thanks for your time and your answers,
Arthur
db.aggregate([
{
$match:{identity:3}
},
{
$project: {all: {$concatArrays: ['$parametres.style.fuel','$parametres.style.gasoline']} }
},
{$unwind: "$all"},
{$match: {"all.type": 'example'}},
{$group : {_id: null, all:{$push:"$all"}}}
])
Probably you are trying to do something like this.
In aggregate operation, the $ is used in right side of : to mention field name and in left side to mention operator.
So when you are using "$all.type" in left-hand side MongoDB is treating it as an operator which is not available in the Mongodb operator list.
Another thing is that when you do any query over an array. Mongodb sends back the full array if atleast one of the element matches the condition. So we need to use $unwind operator to deconstruct the array before doing any query.
I have an objectId like this:
["56153e4c2040efa61b4e267f","56033932efefe0d8657bbd9e"]
To save that information in my model I use:
items: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Items'
}]
What I'm trying to do is to pull an element of the array that is equal to objectId that I send from the front end in a delete request.
The code I'm using:
_.remove(unit.items, request.params.itemId);
I'm using lodash library.
The problem I suppose is that the array have ObjectId elements and I'm trying to compare with an string that is the request.params.itemId.
I have a very similar setup with an "Event" object that has an array of "Assignment" objects saved as an array of ObjectIds. I was able to simply use
obj.arrayField.remove(idToRemove);
Here is the relevant code inside of my delete route handler:
var id = req.assignment._id;
req.event.assignments.remove(id);
req.event.save(function(err, event) {
//etc
}
Does this work for you?
unit.items.remove(request.params.itemId);
You need to pass the string into mongoose.Types.ObjectId('') to get an actual object you can compare against.
So _.remove(unit.items, mongoose.Types.ObjectId(req.params.itemId));
I am attempting to insert items at a specific index in an array that may or may not be empty. For example, say I have the following document in my mongoDb collection:
{
title: "abe",
questions: []
}
I would like to do something like set the 5th element in the array to a specific value. I was playing with the mongo db command line and I was able to do the following:
> mytest = []
[ ]
> mytest[4] = 'test'
test
> mytest
[ undefined, undefined, undefined, undefined, "test" ]
Which is basically what I want, but when I attempt to do this from my node.js code I am getting weird results (weird as in, items are not in the correct index). Code below:
Mongoose Schema Definition:
mongoose = require("mongoose")
Schema = mongoose.Schema
surveySchema = new Schema
title: String
questions: [
type: Schema.Types.ObjectId
ref: 'Question'
]
Code doing the update:
surveys.update {id: doc.survey_id},
{
$push: {
questions: {
$each: [doc._id],
$position: doc.sort_order
}
}
},
{upsert:false, multi:true},
callback
The code above is being executed in an asynchronous loop, so it's possible the last item will be inserted before the first item and so on.
Can anyone see any reason why items would not be getting inserted at the correct index? Why does my basic example work but the code does not? Could it have to do with the fact that my schema defines questions as an array of ObjectIds?
Documentation for MongoDB $position:
If the number is greater or equal to the length of the array, the $position modifier has no effect and the operator adds elements to the end of the array.