Query mongodb collection into nested array - node.js

I have a model called List.js that looks like this:
module.exports = function(mongoose, models) {
var collection = 'List',
Schema = mongoose.Schema;
var schema = new Schema({
promotor: String,
nombre_promotor: String,
cod_evento: {type: Schema.Types.ObjectId, ref: 'Evento'},
lista: [{
nombre: String,
cod_usuario_lider: {
type: Schema.Types.ObjectId,
ref: 'Usuario'
},
usuarios_agregados: [{
cod_usuario: {
type: Schema.Types.ObjectId,
ref: 'Usuario'
},
nombre: String,
fbid: String,
tipo_usuario: Number
}]
}]
});
this.model = mongoose.model(collection, schema);
return this;
}
Im trying to find the documents that match with cod_usuario_lider in the field "lista" and the ones that match with "cod_usuario" in "usuarios_agregados" inside "lista". The first part of the query returns the matched documents, but the second part doesnt return nothing. Anyone knows the proper way to do that query?
var codigo_buscar=req.body.codigo_buscar;
models.List.find({
$or: [{
lista: {
$elemMatch: {
cod_usuario_lider: codigo_buscar
}
}
}, {
usuarios_agregados: {
$elemMatch: {
cod_usuario: codigo_buscar
}
}
}]
})
.exec(function(err, data) {
console.log(data);
});
The first part of the query returns the matched documents, but the second part doesnt return nothing. Anyone knows the proper way to do that query?

From your document, it looks like usuarios_agregados is an attribute to lista. In that case you have to query as below:
var codigo_buscar=req.body.codigo_buscar;
models.List.find({
$or: [{
lista: {
$elemMatch: {
cod_usuario_lider: codigo_buscar
}
}
}, {
lista.usuarios_agregados: {
$elemMatch: {
cod_usuario: codigo_buscar
}
}
}]
})
.exec(function(err, data) {
console.log(data);
});

Related

Fulltext search engine with mongoose and node js not working properly

I am implementing full text search engine in my personal collection app in which there users, collections and items. When user searches , if even it is a comment inside item , it should be displayed. So i tried with text string of mongoose but it is working only with seperate schemas . Ex: only in collection schema or in items schema. I want to create only one route in which i should be able to search everything inside items and collection, even comments inside items. Here is what i have for now but it is giving me only collections property not referecned items schema details:
Collection schema
const collectionSchema = new Schema(
{
name: { type: String },
description: { type: String },
topic: { type: String },
image: { type: String },
customFields: [{ type: Object }],
owner: { type: Schema.Types.ObjectId, ref: "User" },
items: [{ type: Schema.Types.ObjectId, require: true, ref: "Item" }],
},
{ timestamps: true }
);
Collection Route
collectionRoute.get("/search", async (req, res, next) => {
try {
const { title } = req.query;
const searchitem = await CollectionModal.find({
$text: { $search: title },
});
res.status(200).send(searchitem);
} catch (error) {
next(error);
}
});

i have a mongoose schema can any one please tell me how i can insert data into it through create method

this is my schema i want to know how can i add data through create method in the
qurestion field please help
const mongoose = require("mongoose");
const QuizSchema = mongoose.Schema({
course: {
type: mongoose.Schema.Types.ObjectId,
ref: "course"
},
topic: {
type: mongoose.Schema.Types.ObjectId,
ref: "topic"
},
starttime: {
type: Date,
require:true,
},
endtime: {
type: Date,
require: true,
},
qusetions: [
{
qustiontext: {
type: String,
},
correctans: {
type: String,
},
ansoptions: [
{
anstext: {
type: String
}
}
]
}
],
students: [
{
student: {
type: mongoose.Schema.Types.ObjectId,
ref: "student"
},
selectedans: [
{
anstext: {
type: String
}
}]}],
},
{
timestamps:true,
});
const Quizmodel=mongoose.model("quiz" ,QuizSchema);
module.exports=Quizmodel;
For inserting data into the question field in one document, see the code below.
// fetch the quiz document you want to edit.
const quiz = await Quizemodel.findById(_id);
// edit question field.
quiz.questions.push({qustiontext: '', correctans: '', ...})
// save the document
await quiz.save()
For creating documents and saving them to the database see the code below:
const quiz = new Quizmodel({
topic: ...,
starttime: ...,
...
});
quiz.save(function (err) {
if (err) return handleError(err);
// saved!
});
or with the create method:
Quizmodel.create({
topic: ...,
starttime: ...,
...
}, function (err, small) {
if (err) return handleError(err);
// saved!
});
more details at mongoose documents!

How do I return all documents that contain a relationship of a particular ID in Mongoose?

I want to search and return all 'plays' based on if a relationship exists in the 'payees' array using mongoose and Node.js.
Here is the schema:
const playSchema = new Schema({
streamer: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
song: { type: mongoose.Schema.Types.ObjectId, ref: 'Song' },
revenue: { type: Number },
createdAt: { type: Date },
payees: [ { type: mongoose.Schema.Types.ObjectId, ref: 'User' } ]
});
And here is what I am trying to do (just an example):
Play.aggregate([{ $match: { payees: { req.user.id } } }]);
You can use the $elemMatch operator.
The $elemMatch operator matches documents that contain an array field
with at least one element that matches all the specified query
criteria.
Playground
Sample route:
router.get("/plays", async (req, res) => {
const userId = req.user.id;
try {
let docs = await Play.find({
payees: {
$elemMatch: {
$eq: userId
}
}
});
res.send(docs);
} catch (err) {
console.log(err);
res.status(500).send("Something went wrong");
}
});

How to find documents inside ref object without an id?

I have two documents in mongodb:
export const Category = mongoose.model('Category', new mongoose.Schema({
name: { type: String },
}));
export const SubCategory = mongoose.model('SubCategory', new mongoose.Schema({
name: { type: String },
category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' },
}));
How to find All SubCategory that match Category by name?
I have try a lot of ways but I always getting null or error...
var name = '...';
SubCategory.find({ category: { name } });
SubCategory.find({ category: { name } }).populate('category');
You can use aggregation for the same. Please read this documentation https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/
Note:- This answer is based on your collection and data you have entered. this is not perfect but this will help best to find the logic from this answer. :-)
//collection 1 schema
const collection1Schema = new Schema({
user_id: {
type: String,
required: true
},
status: {
type: String
}
});
mongoose.model('Collection1', collection1Schema);
//collection 2 schema
const collection2Schema = new Schema({
user_id: {
type: Schema.Types.ObjectId,
ref: 'user_id'
},
item: {
type: String
}
});
mongoose.model('Collection2', collection2Schema);
//find data from collection2
Collection2.find()
.populate('user_id')
.exec(function(err, foundDocuments) {
if (error) {
console.error(err);
} else {
console.log(foundDocuments);
}
});
For more info:- Mongoose populate

Why $pull does not work when using mongodb on node js [duplicate]

i'm trying to do a pretty simple operation, pull an item from an array with Mongoose on a Mongo database like so:
User.update({ _id: fromUserId }, { $pull: { linkedUsers: [idToDelete] } });
fromUserId & idToDelete are both Objects Ids.
The schema for Users goes like this:
var UserSchema = new Schema({
groups: [],
linkedUsers: [],
name: { type: String, required: true, index: { unique: true } }
});
linkedUsers is an array that only receives Ids of other users.
I've tried this as well:
User.findOne({ _id: fromUserId }, function(err, user) {
user.linkedUsers.pull(idToDelete);
user.save();
});
But with no luck.
The second option seem to almost work when i console the lenghts of the array at different positions but after calling save and checking, the length is still at 36:
User.findOne({ _id: fromUserId }, function(err, user) {
console.log(user.linkedUsers.length); // returns 36
user.linkedUsers.pull(idToDelete);
console.log(user.linkedUsers.length); // returns 35
user.save();
});
So it looks like i'm close but still, no luck. Both Ids are sent via the frontend side of the app.
I'm running those versions:
"mongodb": "^2.2.29",
"mongoose": "^5.0.7",
Thanks in advance.
You need to explicitly define the types in your schema definition i.e.
groups: [{ type: Schema.Types.ObjectId, ref: 'Group' }],
linkedUsers: [{ type: Schema.Types.ObjectId, ref: 'User' }]
and then use either
User.findOneAndUpdate(
{ _id: fromUserId },
{ $pullAll: { linkedUsers: [idToDelete] } },
{ new: true },
function(err, data) {}
);
or
User.findByIdAndUpdate(fromUserId,
{ $pullAll: { linkedUsers: [idToDelete] } },
{ new: true },
function(err, data) {}
);
I had a similar issue. I wanted to delete an object from an array, using the default _id from mongo, but my query was wrong:
const update = { $pull: { cities: cityId }};
It should be:
const update = { $pull: { cities: {_id: cityId} }};

Resources