Pushing object into array using MongoDB syntax and SimpleSchema validation - javascript

The idea is to push an object that looks like this into a field called likes, which is an array:
{
movieId: "VgtyvjVUAjf8ya",
information: {
genre: "Action",
length: "160",
language: "English"
}
}
I thought this would do it:
Meteor.users.update({_id: Meteor.userId()}, {$push: {likes: {movieId: movieId, information: informationObj}}})
But either it is wrong or the validation by SimpleSchema has some issues (it doesn't complain, though) because all I get is an empty object in an array! And no, there's nothing wrong with the values themselves, I have checked.
The SimpleSchema for the field in question looks like this:
likes: {
type: [Object],
optional: true
}
I've tried reading through the documentation but I don't really understand what's wrong. Anyone knows?

If you don't care to validate the objects that get pushed into the likes property, you can set blackbox to true in your schema, like so:
likes: {
type: [Object],
optional: true,
blackbox: true
}
This will allow you to put whatever you want into a "like" object.
If you do want to validate the "like" objects, then you'll need to create some additional schemas, like so:
var likeInfoSchema = new SimpleSchema({
genre: {
type: String
},
length: {
type: String
},
language: {
type: String
}
});
var likeSchema = new SimpleSchema({
movieId: {
type: String
},
information: {
type: likeInfoSchema
}
});
Meteor.users.attachSchema(new SimpleSchema({
// ...
likes: {
type: [likeSchema]
}
}));

Related

How to get an array element in the same index as the query in mongoose

I have the following Schema:
const PublicationSchema = mongoose.Schema({
title: {
type: String,
required: true
},
files:[{
contentType: String,
data: Buffer,
name: String
}]
})
What I'm trying to do is to get the file with the same index as the query.For example I have this object:
_id: new ObjectId("637f20ce6ce5c48d9788a1ff"),
title: 'TEST',
files: [
{
contentType: 'application/pdf',
name: 'imId1',
_id: new ObjectId("id1")
},
{
contentType: 'application/pdf',
name: 'imId2',
_id: new ObjectId("id2")
}
]
where if I query id2 it only retrieves:
{
contentType: 'application/pdf',
name: 'imId2',
_id: new ObjectId("id2")
}
What I was trying to use was const onePublication = await Publication.findOne({ "files._id": req.body.fileId},{}) but this retrieves every field.
I was going to just tell it to not retrieve the other field using field:0 but I realized that this will still retrieve the files in other indexes of the field.
Is there a way to tell it to only retrieve the one with the same index or should I be using another query entirely?
One of the options is to $unwind the array first. $match by your criteria. Then, $replaceRoot to get your array entry.
db.collection.aggregate([
{
"$unwind": "$files"
},
{
$match: {
"files._id": "id2"
}
},
{
"$replaceRoot": {
"newRoot": "$files"
}
}
])
Mongo Playground
Consider changing your schema to store files as an individual collection, if most of the time you are going to access the array objects only.

Update boolean value inside of nested array Mongoose

I have a Schema that holds an array of objects for comments and I would like to update the boolean value of the flagged comments accordingly, I have tried updateOne and aggregate but it isn't working out at this point, I have also tried to use $elemMatch but it isn't working.
The comment _id is being pulled from the front end element that has an ID that is the same as the id that needs to be pulled from MongoDB.
Comments Array within the question Schema:
comments: [
{
user: {
type: Object,
},
commentDate: {
type: Date,
default: Date.now()
},
flagged: {
type: Boolean,
default: false
},
flaggedDate:{type: Date},
comment: String,
}
],
function I tried to run last.
const id = req.params.id
const updateFlag = Question.updateOne(
{
comments: [
{
_id: id
}
]
},
{
$set: {
comments: [
{
flagged: req.body.flagged
}
]
}
}
)
Any help would be appreciated!
You can do it with positional operator - $:
db.collection.update({
"comments._id": "3"
},
{
"$set": {
"comments.$.flagged": true
}
})
Working example

mongoose add more key:value inside ref field

organs: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Organ',
healthValue: { // i want to add this field but it is becoming invalid, not generating auto with default val
type: Number,
default: 0,
}
},
],
I have a user schema and also there is organs key in this schema. I'm keeping organs with ref way to get belongs to user organs. I also should keep organ health value but I can not keep it in ref field together as above. How can i do this? Can not I add more key:value to populate (type & ref) fields?
organs: [
{
organId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Organ',
},
healthValue: {
type: Number,
default: 0,
},
isOwned: {
type: Boolean,
default: false,
},
},
],
i think i solve with above code block, i did use wrong syntax

Updating an array inside a Mongoose Model

I have to do an update on the following Mongoose Model.
var room_schema = new Schema({
title: { type: String, required: true },
questions: [{ //array of reflections
q_index: {type: Number},
q_text: { type: String},
responses: [{ //array of
student: { type: Schema.Types.ObjectId, ref: 'User' },
response: { type: String }
}]
}]
});
module.exports = mongoose.model('Room', room_schema);
Required values are in an object as
x = {
room: ObjectId("586a0aa0232a3918c8b7f5c9"),
student: ObjectId("5863918c85c9ba0aa0232a7f"),
question: 0,
msg: "Some Message"
}
Now, i want to update the room. I tried doing something like this
Room.update(
{_id:x.room,
'questions.q_index':x.question,
'questions.responses.student':x.student},
{$set:{
'responses.$.student.response' : x.msg
}},function(err, data){
if(err){throw err}
console.log(data);
}
);
The msg which is being returned is { ok: 0, n: 0, nModified: 0 } and needless to say the update is not happening.
Also, there is a possibility that the Room may not have a response array in it. And i expect that, if that is the case, then the array should be created and then updated.
Please give me some guidance.
Sry, but I can't write a comment since I don't have enough of rep, so I'm forced to write my notice as an answer.
I notice something in your first query when you search for a room by it's _id. Try to put _id in quotes like this "_id", because it should be like this relating to this post
stackoverflow: updating-an-array-inside-a-mongoose-model

Storing Javascript Array of Objects in Mongo DB using Mongoose

I have an array of the form [{key: ..., type: ..., value: ...}] and want to store it in the fields field in the following schema:
var articleSchema = mongoose.Schema({
name: {
type: String,
unique: true,
required: true
},
updated: {
type: Date,
default: Date.now
},
pageviews: {
type: Number,
default: 0
},
fields: [{
key: String,
type: String,
value: String
}],
image: String
});
I am doing this as follows, my Javascript array referenced as keyValueObj
Article.findOneAndUpdate(
{ name: articleName },
{
fields: keyValueObj
},
{ upsert: true },
callback
);
However, all that is stored in the database in the fields field is an array of strings like this: ["[object Object]"]
How can I store my Javascript array so that it matches my mongoose schema correctly?
I was able to fix this using Molda's idea of using a separate schema.
The updated fields field in the articleSchema now looks like this:
fields: [{
type: Schema.Types.ObjectId,
ref: 'Field'
}]
I then converted the array to an array of schema objects, like this:
keyValueObj = keyValueObj.map(function(fieldObj){
return new Field({
key: fieldObj.key,
type: fieldObj.type,
value: fieldObj.value
});
});
I was then able to store keyValueObj the was doing it in the initial code.

Categories

Resources