Thanks in advance, Why I am getting an empty array from the Mongodb even though using the correct schema name?
const Mongoose = require("mongoose");
const studentSchema = Mongoose.Schema({
_id: { type: Number, required: true },
name: { type: String, required: true, max: 30 },
department: { type: String, required: true,max: 30 },
type: { type: String, required: true, min: 7, max: 30 }
});
module.exports = Mongoose.model("StudentInformation", studentSchema);
-----------------------------------------------------------------------
class Service {
static get() {
const data = studentsModel.find({}).then((result) => {
console.log(studentsModel)
return result;
});
return data;
}
}
----------------------------------------------------------------------
```
> db.getCollectionNames();
[ "StudentInformation", "students" ]
> db.StudentInformation.find();
{ "_id" : 1, "name" : "selva", "department" : "CSE", "type" : "regular" }
{ "_id" : 2, "name" : "ashik", "department" : "CSE", "type" : "regular" }
{ "_id" : 3, "name" : "praveen", "department" : "CSE", "type" : "parttime" }
You have a wrong "return" instruction in your get() function:
static get() {
const data = studentsModel.find({}).then((result) => {
console.log(studentsModel)
return result;
});
**return data;**
}
This part is asynchrone
studentsModel.find({}).then((result) => {
Your returning data which is empty / undefined before the execution of the find callback
Related
I got this user schema
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
groups: [
{
groupName: {
type: String,
required: true,
},
groupMembers: [{ type: Schema.Types.ObjectId, ref: "GroupMember" }],
},
],
});
And I want to delete a group from the ‘groups’ array based on given ‘userId’ and ‘groupId’, my attempt (with express and mongoose):
router.delete(
"/:userId/:groupId",
catchAsync(async (req, res) => {
const { userId, groupId } = req.params;
const updatedUser = await User.findByIdAndUpdate(
userId,
{ $pull: { "groups.$._id": groupId } },
{ new: true }
);
res.send({ updatedUser });
})
);
The response of the request: I get an error: “The positional operator did not find the match needed from the query.”
Edit:
After I delete a group I need to remove all the group members in the groupMembers array.
User collection structure example:
{
"_id" : "111",
"email" : "michael#gmail.com",
"username" : "michael098",
"groups" : [
{
"_id" : "222"
"groupName" : "family",
"groupMembers" : [
{
"_id" : "333"
"name" : "Liam"
},
{
"_id" : "444"
"name" : "Noah"
}
]
},
{
"_id" : "555"
"groupName" : "friends",
"groupMembers" : [
{
"_id" : "666"
"name" : "Oliver"
}
]
}
]
}
Inside every group there is group members and I have a collection for the group members that I ref in the UserSchema : groupMembers: [{ type: Schema.Types.ObjectId, ref: "GroupMember" }]
GroupMember collection structure example:
{
{
"_id" : "333"
"name" : "Liam"
},
{
"_id" : "444"
"name" : "Noah"
},
{
"_id" : "666"
"name" : "Oliver"
}
}
For example when I get the params of userId="111" and groupId="222" I will delete the whole 'family' group and the whole group members in the groupMembers array (Liam and Noah) from the GroupMember collection.
GroupMember collection after deleting the group with _id="222":
{
{
"_id" : "666"
"name" : "Oliver"
}
}
Assuming an actual doc might look like this (using strings instead of ObjectId to keep the example tighter):
{_id:1, groups: [ { type: "ID1", ref: "XX" }, { type: "ID2", ref: "G1" }, { type: \
"ID3", ref: "G2" } ] }
then this update will remove the subdoc in the groups array where _id = 1 and type = ID2:
db.foo.update({_id:1},
{ $pull: { groups: { type: "ID2" } }}
);
This question already has answers here:
How to push an array of objects into an array in mongoose with one call?
(4 answers)
Closed 3 years ago.
I'm using Angular 7 with node.js, express and mongoose
I have a problem when adding objects to my mongodb via mongoose, it saves only "_id": ObjectId('randomID') instead of the values i want.
I'm trying to add values to an existing document in my collection with nested arrays.
To be more precise: there are customers with a customer number, customer name and domains.
Domains shall be an array with a domain.
A domain has a name value and two more arrays (called "in" & "out")
both arrays contain a graph array with nodes and links.
nodes have 3 values (id, label, description) and links have also 3 values (source, target, label)
First Problem I have, is that I cant add new domain to my domains array
I don't understand what am I am doing wrong??
Or what is best practice to insert and/or update nested arrays inside nested arrays?
edit: I try to understand, why am I saving only the ObjectId() with no values, linked question doesn't work for me.
here is an Example of what i want in my db:
{
"_id" : ObjectId("5c76a093aac6fa3f140a5672"),
"KdNr" : "10004",
"Kundenname" : "Customer GmbH",
"__v" : 0,
"domains" : [ {
"domain" : "testB.de",
"in" : [ {
"content" : "New Graph B",
"graph" : { ... } } ],
"out" : [ {
"content" : "Another new Graph B",
"graph" : { ... } } ]
}, [ {
"domain" : "testA.de",
"in" : [ {
"content" : "New Graph A",
"graph" : { ... } } ],
"out" : [ {
"content" : "Another new Graph A",
"graph" : { ... } } ]
} ]
}
here is an Example of what i get (not what I want):
{
"_id" : ObjectId("5c76a093aac6fa3f140a5672"),
"KdNr" : "10004",
"Kundenname" : "Customer GmbH",
"__v" : 0,
"domains" : [ {
{ "_id" : ObjectId("5c7f86ad42d63141fc921d04") },
{ "_id" : ObjectId("5c655c828be0b2b295aa126f") }
] }
here is my Schema:
const mongoose = require('mongoose');
const graphSchema = mongoose.Schema({
graph: {
nodes: [{
id: { type: String, required: true, unique: true },
label: { type: String, required: true },
description: { type: String }
}],
links: [{
source: { type: String, required: true },
target: { type: String, required: true },
label: { type: String }
}]
}
});
const domainSchema = mongoose.Schema({
domain: {
name: { type: String, unique: true, required: true },
in: {
content: { type: String },
graphSchema
},
out: {
content: { type: String },
graphSchema
}
}
});
const diagramSchema = mongoose.Schema({
KdNr: { type: String, required: true, index: true, unique: true },
Kundenname: { type: String, required: true },
domains: [{
domainSchema
}]
});
module.exports = mongoose.model('Diagram', diagramSchema);
here is my domains-routes.js:
// core Modules
const express = require('express');
// own modules
const Diagram = require('../models/diagrams');
const router = express.Router();
// add Domain to Diagram
router.put('/:KdNr', (req, res, next) => {
console.log(req.body.domain);
const data = {
domains : [{
domain: req.body.domain,
in: [{
content : "New Graph",
graph : {}
}],
out: [{
content : "New Graph",
graph : {}
}]
}]
}
Diagram.updateOne(
{ KdNr: req.params.KdNr },
{ $push: data }
).then(result => {
if(result) {
console.log('Diagram found in database:');
console.log(result);
res.status(200).json({ message: 'Diagram saved' });
} else {
res.status(404).json({ message: 'Diagram for customer: '
+ req.params.KdNr + 'not found!'})
}
})
})
module.exports = router;
Try this in
Diagram.updateOne
{ $push:{"domains": data }}
So I have this schema for a Supplier:
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
Address = require('./Address.js'),
AddressSchema = mongoose.model('Address').schema,
Product = require('./Product.js'),
ProductSchema = mongoose.model('Product').schema;
// Create a new schema for the reviews collection with all the relevant information for a review
var Schema = mongoose.Schema;
var Supplier = new Schema(
{
name: String,
address: AddressSchema,
location: {
type: {type:String, default: 'Point'},
coordinates: [Number] // [<longitude>, <latitude>]
},
products: [ProductSchema]
}
);
Supplier.index({location: '2dsphere'});
var SupplierModel = mongoose.model('Supplier', Supplier );
// export the review model
module.exports = SupplierModel;
Products in my system have a "verified" field which is a boolean. In one of my routes I would like to query the DB to find all the suppliers which have products which aren't verified such that I can then render those products in the page.
I tried this, but unofrtunatelly it returns all the subdocuments no matter if "verified" is true or false:
exports.admin_accept_product_get = function (req, res) {
Supplier.find({'products.verified' : false}, function(err, docs) {
res.render('admin_accept_product', { user : req.user, suppliers: docs });
});
};
Any help is appreciated
Edit:
The previous query would return the following data:
{
"_id" : ObjectId("5b2b839a2cf8820e304d7413"),
"location" : {
"type" : "Point",
"coordinates" : [
-16.5122377,
28.4028329
]
},
"name" : "Tienda1",
"products" : [
{
"verified" : true,
"_id" : ObjectId("5b2b83d32cf8820e304d7420"),
"title" : "Vodka",
"inStock" : 15,
"typeOfItem" : "alcohol",
"sellingPrice" : 15,
"image" : "public/upload/15295784515201529168557789bottle.png",
"typeOfAlcohol" : "vodka"
},
{
"verified" : false,
"_id" : ObjectId("5b2b848f8c59960c44df09cd"),
"title" : "Whisky",
"inStock" : 40,
"typeOfItem" : "alcohol",
"sellingPrice" : 15,
"image" : "public/upload/15295786395491529323314298whisky.png",
"typeOfAlcohol" : "whisky"
}
],
"__v" : 2
}
I would like my query to not return the firt product because "verified == true"
You need to use $elemMatch to find the document and $elemMatch for projection of the data
db.collection.find({
products: {
$elemMatch: {
verified: false
}
}
},
{
products: {
$elemMatch: {
verified: false
}
},
location: 1
})
Output
[
{
"_id": ObjectId("5b2b839a2cf8820e304d7413"),
"products": [
{
"_id": ObjectId("5b2b848f8c59960c44df09cd"),
"image": "public/upload/15295786395491529323314298whisky.png",
"inStock": 40,
"sellingPrice": 15,
"title": "Whisky",
"typeOfAlcohol": "whisky",
"typeOfItem": "alcohol",
"verified": false
}
]
}
]
Check it here
The Data stored in my db is:
{
"_id" : ObjectId("58da135cfc80bc44f7653fd4"),
"updatedAt" : ISODate("2017-03-28T08:00:59.541Z"),
"createdAt" : ISODate("2017-03-28T07:40:12.742Z"),
"name" : "hello",
"delete" : false,
"enabledPlugins" : [
ObjectId("58c24f65b363502f907738f9")
],
"__v" : 0
}
My Schema Like:
const mongoose = require('./db');
const { Schema } = mongoose;
const templateSchema = new Schema({
name: { type: String, index: true, unique: true },
enabledPlugins: [
{ type: Schema.Types.ObjectId }
],
delete: { type: Boolean, default: false }
}, {
timestamps: true
});
const Template = mongoose.model('Template', templateSchema);
module.exports = Template;
But When I want to get templates, I get the wrong timestamp:
exports.getAllTemplates = async function() {
return await Template.aggregate(
{ $match: { delete: false } },
{ $project: { id: '$_id', _id: 0, name: 1, enabledPlugins: 1, createdAt: 1 } }
);
};
The result like :
[
{
"createdAt": "2017-03-28T17:04:30.502+08:00",
"name": "hello",
"enabledPlugins": [
"58c24f65b363502f907738f9"
],
"id": "58da135cfc80bc44f7653fd4"
}
]
And I found before toJSON, the output has been wrong. I don't use any plugins. All the date type has the same problem.
Thanks, the problem is that I rewrite Date.prototype.toISOString
I want to create a subdocument in a subobject field, not to update.
My Schema:
var DemandeSchema = new Schema({
titre: {
type: String,
required: true
},
description: {
type: String,
required: true
},
type: {
type: String,
required: true
},
answer: {}
});
My code:
demande.update(
{ name: 'answer' },
{ $push: req.body.answer },
{ upsert: true },
function(error, user) {
if (error) return next(error);
else {
return true;
}
}
)
req.body.answer = {
"id": "57f512f4360d8818a4e5ea3d",
"answer": {
"122547eee99" : {
"review" : "1.3",
"login" : "new"
}
}
}
But this code doesn't create a new field in my DB, it just updates the field answer when I just want to create a new object field in the answer field.
Actual Result:
{
"_id" : ObjectId("57f512f4360d8818a4e5ea3d"),
"titre" : "TEST",
"description" : "ee",
"type" : "ee",
"__v" : 0,
"answer" : {
"122547eee98" : {
"review" : "8.8",
"login" : "x"
}
}
}
Expected Result:
{
"_id" : ObjectId("57f512f4360d8818a4e5ea3d"),
"titre" : "TEST",
"description" : "ee",
"type" : "ee",
"__v" : 0,
"answer" : {
"122547eee98" : {
"review" : "8.8",
"login" : "x"
},
"122547eee99" : {
"review" : "1.3",
"login" : "new"
}
}
}
var DemandeSchema = new Schema({
titre: {
type: String,
required: true
},
description: {
type: String,
required: true
},
type: {
type: String,
required: true
},
answer: []
});
Answer field curly braces would convert to square brackets for pushing all new answers.
Conclusion: It creates an array.
Instead of the $push operator which works on arrays, use the $set operator together with the dot notation to set the subdocument in the embedded answer document.
You would need to preprocess the document to use in your update so that it will have the dot notation. The following mongo shell example demonstrates this:
var obj = {
"id": "57f512f4360d8818a4e5ea3d",
"answer": {
"122547eee99" : {
"review" : "1.3",
"login" : "new"
}
}
},
update = {};
var key = Object.keys(obj.answer)[0]; // get the dynamic key "122547eee99"
update["answer."+key] = obj.answer[key]; // create the update object with dot notation
/*
update = {
"answer.122547eee99": {
"review" : "1.3",
"login" : "new"
}
}
*/
db.demandes.update(
{ "_id" : ObjectId(obj.id)},
{ "$set": update },
{ "upsert": true }
)
Using the same concept as above, you can create the documents to use in your update as follows:
var update = {},
key = Object.keys(req.body.answer.answer)[0]; // get the dynamic key "122547eee99"
// create the update object with dot notation
update["answer."+key] = req.body.answer.answer[key];
demande.update(
{ "_id": req.body.answer.id },
{ $set: update },
{ upsert: true },
function(error, user) {
if (error) return next(error);
else {
return true;
}
}
);
Try this, and in schema answer: [],
demande.findOne( { name: 'answer' }, function(err, result){
result.answer.push({ans:req.body.answer})
var dem = new Demande(result); // Demande is ur mongoose schema model,
dem.save(function(err, result){
console.log(result);
});
})