Add more fields in MapReduce with Mongoose and NodeJS - javascript

I've this mongoose schema
var SessionSchema = mongoose.Schema({
id: Number,
cure: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Cure'
},
performances: Array,
startDate: Date,
endDate: Date,
validatee: Boolean,
deleted: Boolean
});
I need to know how many documents have different ids, but i only need those that have startDate greater than a given date (for example today).
Running the following code works fine but i want to add some fields in map to use them in the query.
var o = {};
o.map = function () {
emit(this.id, 1
// list other fields like above to select them
)
}
o.reduce = function (k, vals) {
return vals.length
}
o.out = {
replace: 'createdCollectionNameForResults'
};
o.verbose = true;
Session.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime)
console.log("MapReduce" + JSON.stringify(model));
model.find().exec(function (err, docs) {
console.log(docs);
});
});
This is my output :
[ { _id: 0, value: 2 },
{ _id: 1, value: 4 },
{ _id: 2, value: 2 } ]
I try to do this:
....
o.map = function () {
emit(this.id, {
startDate: this.startDate
})
}
....
model.find({
startDate: {
"$gte": new Date()
}
}).exec(function (err, docs) {
console.log(docs);
});
....
but I keep getting the same output.
So how do I add more key-value params from the map function to the result dictionary of the reduce function?

This is a solution :
var o = {};
o.map = function () {
emit(this.id, {
startDate: this.startDate,
cure: this.cure,
test: 'test'
// list other fields like above to select them
})
}
o.reduce = function (k, vals) {
return {
n: vals.length,
startDate: vals[0].startDate,
cure: vals[0].cure,
test: vals[0].test
}
}
o.out = {
replace: 'createdCollectionNameForResults'
};
o.verbose = true;
Session.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime);
model.find({
'value.cure':mongoose.Types.ObjectId('52aedc805871871a32000004'),
'value.startDate': {
"$gte": new Date()
}
}).exec(function (err, docs) {
if(!err)
console.log(docs.length);
});
});

Related

How to store only certain fields from NeDB database into an array with NodeJS

I have an embedded NeDB database with numerous entries with multiple fields and I'm looking to only get the dates from every entry and store it into an array. I'm using NeDB, NodeJS and express.
The dataset looks like so:
{"goalName":"swim 5km","details":"I want to swim 5km","date":"2021-05-15","completed":false,"author":"somename","_id":"BMnvTm54rNbwc9D4"}
{"goalName":"swim 5km","details":" I want to swim another 5km","date":"2021-03-14","completed":false,"author":"somename","_id":"EwEicEYZAfFxY9Z6"}
{"goalName":"20 pushups","details":"I want to complete 20 full pushups","date":"2021-05-14","completed":false,"author":"anthername","_id":"rP7q6L8jnwGyAgGD"}
I'm only interested in the dates where the author is somename,
I can retrieve these documents using:
getEntriesByUser(userName) {
return new Promise((resolve, reject) => {
this.db.find({ 'author': userName }, function (err, entries) {
if (err) {
reject(err);
} else {
resolve(entries);
console.log('getEntriesByUser returns: ', entries);
}
})
})
}
which then returns the documents where the username = someusername, but i'm only interested in the dates. Preferably storing them to an array with a result like so:
[2021-05-15, 2021-03-14, 2021-05-14]
How would I got about doing this?
Thanks for your help!
You can use the optional second projection parameter of the find() and findOne() methods to include or omit properties of the returned records. see: NeDB#projections.
db.find({ author: userName }, { date: 1, _id: 0 }, function (err, docs) {...});
const
Datastore = Nedb,
db = new Datastore(),
data = [
{ goalName: "swim 5km", details: "I want to swim 5km", date: "2021-05-15", completed: false, author: "somename" },
{ goalName: "swim 5km", details: " I want to swim another 5km", date: "2021-03-14", completed: false, author: "somename" },
{ goalName: "20 pushups", details: "I want to complete 20 full pushups", date: "2021-05-14", completed: false, author: "anthername" },
];
for (const datum of data) {
db.insert(datum);
}
function getEntriesByUser(userName) {
return new Promise((resolve, reject) => {
db.find({ author: userName }, { date: 1, _id: 0 }, function (err, entries) {
if (err) {
reject(err);
} else {
resolve(entries);
console.log('getEntriesByUser returns: ', entries);
}
})
})
}
getEntriesByUser('somename').then((entries) => {
console.log('Mapped return value: ', entries.map(({ date }) => date));
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/nedb/1.8.0/nedb.min.js"></script>

Unable to query data with mongoose using dates (nodejs)

I'm trying to query all Assistance documents that have the "inputDate" between their startDate and endDate. I've been looking on the internet for ages and I'm unable to make it work. It is suposed to retrieve the only document that right now is in my db. I'm using NodeJS+Mongoose.
The code in the controller is the following:
exports.getOccupation = (req, res, next) => {
var inputDate = new Date("1999","10","13","16","0","0");
Assistance.find({
dateInterval:{
startDate: {$lte:inputDate},
endDate: {$gte:inputDate}
}
})
.then(assistances => {
console.log(assistances.length);
})
}
The code of the model:
const assistanceSchema = new Schema(
{
user_id:{
type: Schema.ObjectId
},
place:{
longitude:{
type:String
},
latitude:{
type:String
}
},
dateInterval:{
startDate: Date,
endDate: Date
}
},
{timestamps:true}
);
I'm not sure, but I believe that find() method accept dateInterval.startDate instead of dateInterval:{startDate: ... }.
Try change this way:
Assistance.find({
$and: [
{ "dateInterval.startDate": { $lte: inputDate } },
{ "dateInterval.endDate": { $lte: inputDate } },
],
}).then((assistances) => {
console.log(assistances.length);
});

How to access array elements that are defined in another array of Mongoose scheme object Array?

This is the User schema in mongoose:
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true,
},
name: {
type: String,
required: true,
},
Addtasks: [
{
topic: String,
words: Number,
keywords: String,
website: String,
otherdetails: String,
exampleRadios: String,
deadline: Date,
Date: String,
fileName: String,
Bigpaths: [],
},
],
});
module.exports = mongoose.model('User', userSchema);
I want to use/access the Bigpaths array, which is defined inside the Addtasks array, which is defined in User. Data is already are there in mongoDB, which I have inserted via UI page. I am trying the following code but I am getting this error in console:
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(
(element) => {
// ...
}
)
as
TypeError: Cannot read property 'Bigpaths' of undefined
at \Desktop\grumpytext\routes\index.js:99:71
Code:
const { files } = req;
User.findOne({ email: req.user.email }, function (error, data) {
if (error) {
console.log('Three');
} else if (data) {
if (Object.keys(data.Addtasks).length > 1) {
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(
(element) => {
files.forEach((currentElement) => {
if (element.name == currentElement.filename) {
files.pull(currentElement.filename);
}
});
}
);
}
}
});
How to resolve this error or how to access all the elements of Bigpaths array so that I can iterate it with forEach loop?
I'm not sure here, but I think you need to populate Addtasks prior to manipulating it:
const files = req.files;
User.findOne({email:req.user.email}).populate('Addtasks').exec((error, data) => {
if (error) {
console.log("Three");
}
else
{
if(data)
{
if(Object.keys(data.Addtasks).length > 1)
{
console.log("Addtasks count: " + Object.keys(data.Addtasks).length);
data.Addtasks[Object.keys(data.Addtasks).length - 2].Bigpaths.forEach(element => {
files.forEach(currentElement => {
if(element.name == currentElement.filename)
{
files.pull(currentElement.filename);
}
})
});
}
}
}
});
Please notice the log console.log("Addtasks count: " + Object.keys(data.Addtasks).length); - in case the solution does not work, I advise to add some prints, especially to check if the count of elements is as expected or properties within an object are fine.

Issue in document insert using mongoose

I have schema created now i want to insert into mongodb collection, but its throwing error diagramModel.insert is not defined any idea what is implemented wrong ?
app.js
mongoose.connect('mongodb://localhost:27017/develop-modeler');
require('./server/api/diagram/diagram.model.js');
var diagramModel = mongoose.model('Diagram');
var newDiagram = {
"owner" : "sh529u",
"text" : "sco_poc.bpmn",
"users":["wp6307","kz323j","ew6980"],
"groups":[],
"string" : "test"
}
mongoose.connection.on('connected', function () {
diagramModel.insert(newDiagram,function(err,res){
if (err) { console.log(err);}
else {
diagramModel.find({}, function(err, data) { console.log(data);});
}
});
});
diagram.model.js
var DiagramSchema = new mongoose.Schema({
text: String,
owner: {type: String, ref:'User'},
groups: [{type: String, ref: 'Group'}],
users: [{type: String, ref: 'User'}],
string: String
});
mongoose.model('Diagram', DiagramSchema);
I think it's save not insert while saving records. That's why you are getting this error
mongoose.connect('mongodb://localhost:27017/develop-modeler');
var diagramModel = require('./server/api/diagram/diagram.model.js');
var newDiagram = {
"owner": "sh529u",
"text": "sco_poc.bpmn",
"users": ["wp6307", "kz323j", "ew6980"],
"groups": [],
"string": "test"
}
mongoose.connection.on('connected', function() {
diagramModel.save(newDiagram, function(err, res) {
if (err) {
console.log(err);
} else {
diagramModel.find({}, function(err, data) {
console.log(data);
});
}
});
});
var DiagramSchema = mongoose.Schema({
text: String,
owner: {type: String, ref:'User'},
groups: [{type: String, ref: 'Group'}],
users: [{type: String, ref: 'User'}],
string: String
});
module.exports=mongoose.model('Diagram', DiagramSchema);
Create a new instance of your model and this instance contains a save method:
mongoose.connect('mongodb://localhost:27017/develop-modeler');
require('./server/api/diagram/diagram.model.js');
var diagramModel = mongoose.model('Diagram');
var newDiagram = new diagramModel({
"owner" : "sh529u",
"text" : "sco_poc.bpmn",
"users":["wp6307","kz323j","ew6980"],
"groups":[],
"string" : "test"
});
mongoose.connection.on('connected', function () {
newDiagram.save(function(err,res){
if (err) { console.log(err);}
else {
diagramModel.find({}, function(err, data) { console.log(data);});
}
});
});
Try this its working perfect
var diagramModel = require('./server/api/diagram/diagram.model.js');
var finalDiagram = diagramModel({
"owner" : "sh529u",
"text" : "sco_poc.bpmn",
"users":["wp6307","kz323j","ew6980"],
"groups":[],
"string" : "test"
});
mongoose.connection.on('connected', function () {
finalDiagram.save(function (err, dataObj) {
if (err) { console.log(err);}
} else {
console.log("DATA",dataObj);
diagramModel.find({}, function(err, data) { console.log(data);});
}
});
});

Populate not working for an array of ObjectIDs

This is the implementation of my models :
var itemSchema = new Schema({
name : String,
qte : Number
});
var Item = mongoose.model('Item', itemSchema);
var orderSchema = new Schema({
state : {
type: String,
enum: ['created', 'validated', 'closed', 'starter', 'meal', 'dessert'],
required : true
},
table : {
number : {
type : Number,
required : true
},
name : {
type : String,
required : false
}
},
date: { type: Date, default: Date.now },
_items : [{type:Schema.Types.ObjectId, ref:'Item'}]
});
And this is how I do my query
getByIdRaw : function (orderId, callback) {
Order.findById(orderId)
.populate('_items')
.exec(function(err, order) {
debug(order);
callback(order);
});
}
This is my response without populating
{
_id: "5549e17c1cde3a4308ed70d5"
state: "created"
_items: [1]
0: "5549e1851cde3a4308ed70d6"
-
date: "2015-05-06T09:40:12.721Z"
table: {
number: 1
}-
__v: 1
}
...and my response when populating _items
{
_id: "5549e17c1cde3a4308ed70d5"
state: "created"
__v: 1
_items: [0]
date: "2015-05-06T09:40:12.721Z"
table: {
number: 1
}-
}
Why the _items array is empty ? What am I doing wrong ?
EDIT : the addItem function
addItem : function (orderId, item, callback) {
Order.findById(orderId)
.exec(function(err, order) {
if (err) {
error(err);
return callback(err);
}
if (order === null) {
return callback("No order with this id");
}
var newItem = new Item({
name : item.name,
qte :item.qte
});
order._items.push(newItem);
order.markModified('_items');
order.save();
callback();
});
}
The issue is the new item is never persisted to the items collection. Mongoose references only populate they don't persist a new item to the referenced collection.
addItem: function(orderId, item, callback) {
var newItem = new Item({
name: item.name,
qte: item.qte
});
newItem.save(function(err, savedItem) {
if (err) {
error(err);
return callback(err);
}
Order.findById(orderId).exec(function(err, order) {
if (err) {
error(err);
return callback(err);
}
if (order === null) {
return callback("No order with this id");
}
order._items.push(savedItem);
order.markModified('_items');
order.save(callback);
});
});
}

Categories

Resources