mongoose "_id" vanishing in collection created with map/reduce - node.js

I done a very simple map/reduce in mongo console.
var mapState = function () {
emit(this.state, 1);
};
var sumState = function (keyState, valuesCount) {
return Array.sum(valuesCount);
};
db.FooBar.mapReduce(
mapState,
sumState,
{out: "state_counts"}
);
var sc = {};
db.state_counts.find(
{_id: {$exists: true}}).forEach(
function(o){
sc[o._id]=o.value;
}
);
> sc
{
"ak" : 29,
"al" : 5832,
"ar" : 2798,
...
}
> db.state_counts.find().limit(3)
{ "_id" : "ak", "value" : 29 }
{ "_id" : "al", "value" : 5832 }
{ "_id" : "ar", "value" : 2798 }
So far so good. I have the expected state abbreviations and counts in the "sc" object. Oddness occurs when I'm attempting to pull data from state_counts prior to converting it to the equivalent of the "sc" object using mongoose.
#!/usr/bin/env node
mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/thedb");
var schema = new mongoose.Schema({});
schema.collection = 'state_counts';
console.log(schema.collection);
var cur = mongoose.model(schema.collection, schema);
cur.find({}).exec(
function(err, data) {
if (err) {
console.log(err);
mongoose.disconnect();
}
console.log(data);
mongoose.disconnect();
}
);
$ ./test.js
state_counts
[ { value: 29 },
{value: 5832 },
{ value: 2798 },
...
]
This is surprising to me. Why is the "_id" value not showing up in my script when using mongoose?

_id isn't showing up because you haven't defined a schema and mongoose is all about adding schemas to mongodb. So given a completely empty schema, mongoose probably assumes _id will be of type ObjectId (which is conventional for mongodb) and when casting the data in mongodb to that type fails, as it will always do given your data, mongoose omits the value, which makes sense given the majority of mongoose's job is to enforce a consistent schema. This will "fix" it.
var schema = new mongoose.Schema({_id: String, value: Number});

Related

insert and insertOne not a function and update not creating mongo ID

I thought I could read my way to this solution, but I cant see what im doing wrong.
Here is my model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var inspectSchema = new Schema({
_id: Object, // Mongo ID
property: String, // Property ID
room: String, // The room Name
item: Array // The Items text
});
module.exports = mongoose.model('inspectModel', inspectSchema, 'inspect');
And here is where I try to insert or insertOne
var inspectModel = require('../../models/inspectModel');
var inspectTable = mongoose.model('inspectModel');
inspectTable.insert(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
},
function (err, res) {
if (err) { return reject({err:true, err:"addInspect ERROR" + err}) }
else {
show("=====RESOLVE addInspect=====")
return resolve();
}
})
I tried
inspectTable.insert
inspectModel.insert
inspectTable.insertOne
inspectModel.insertOne
No matter what I always get
TypeError: inspectTable.insert is not a function
I also tried just update with { upsert: true } but then the mongo ID becomes null.
Any ideas?
The method you're looking for is create:
inspectTable.create(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
}, ...
However, your schema definition of _id: Object is likely wrong. Just leave any definition of _id out of your schema and it will use the default ObjectId, which is likely what you want.
You can try this
var insert_table = new inspectTable(
{
"property" : inspectRecord.property,
"room" : inspectRecord.room,
"item" : inspectRecord.item
});
insert_table.save(function (err, res) {
if (err) { return reject({err:true, err:"addInspect ERROR" + err}) }
else {
show("=====RESOLVE addInspect=====")
return resolve();
}
});

mongoose find not fetching any result

I've simple collection in mongo and a corresponding mongoose model. This collection will only contain one document always. When I run a query in mongoshell it is giving me the result, but when I try to do findOne using mongoose it is not returning any result at all. Can someone help me figure out what is wrong. Below is my code.
Model:
const mongoose = require('mongoose');
const schema = new mongoose.Schema({
lastResetMonth: {
type: Number
},
lastResetWeek: {
type: Number
},
currentFisYear:{
type: Number
}
});
module.exports = mongoose.model('ReserveResetTrack', schema, 'reserveResetTrack');
const ReserveResetTrack = require('../models/ReserveResetTrack');
ReserveResetTrack.findOne({})
.then(trackData => {
return {
lastFisMonth: trackData.lastMonth,
lastFisWeek: trackData.lastWeek
}
});
The above code is always returning nothing but a promise.
This is the only document i've in my collection and this will be the only one for ever
{
"_id" : ObjectId("589271a36bfa2da821b13ce8"),
"lastMonth" : 0,
"lastWeek" : 0,
"currentYear" : 0
}
Use exec() like this:
ReserveResetTrack.findOne({})
.exec() // <--- use exec() here
.then(trackData => {
return {
lastFisMonth: trackData.lastMonth,
lastFisWeek: trackData.lastWeek
}
});

MongoDB / Mongoose $pull (remove) Sub Document not working

Smashing my head into the keyboard over this.
Simply need to remove subdocument. Example below only has one item in OnCommands but there could be a many items there. I have tried find, findbyid, updatebyId, pull, one things after another. Tried by _id of subdoc and by generic searchinMost simple run without doing anything no errors.
I would be so greatful if you can show me what I am doing wrong, it's the last part of my code that isn't work.
Sample Data:
> db.EntryPoints.find({_id: ObjectId("569e4fabf1e4464495ebf652")}).pretty()
{
"__v" : 0,
"_id" : ObjectId("569e4fabf1e4464495ebf652"),
"name" : "bbbb",
"offCommands" : [ ],
"onCommands" : [
{
"data" : "11111",
"operation" : "on",
"command" : "ISY-HTTPGet",
"_id" : ObjectId("569e4faff1e4464495ebf653")
}
]
Model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var onCommandsSchema = new Schema({
command: String
,operation: String
,data: String
})
var offCommandsSchema = new Schema({
command: String
,operation: String
,data: String
})
mongoose.model('onCommands', onCommandsSchema);
mongoose.model('offCommands', offCommandsSchema);
// create a schema
var EntryPointsSchema = new Schema({
name: String
,onCommands: [onCommandsSchema]
,offCommands: [offCommandsSchema]
,description: String
}, { collection: 'EntryPoints' });
mongoose.model('EntryPoints', EntryPointsSchema);
var EntryPoints = mongoose.model('EntryPoints');
module.exports = EntryPoints;
Node Post Code:
router.post('/webservices/removeCommand', function (req, res) {
var EntryPoints = require('../data_models/automate_entrypoints.js');
EntryPoints.update(
{ _id: ObjectId(req.body._id) }
, {
$pull: {
onCommands: { id_: req.body._id }
}
}
, function (err, ouput) { console.log("data:", numAffected) }
);
});
Your code won't work because of the query part of your update: you want to match on the embedded document's _id, not on the main document. So change it to
var EntryPoints = require('../data_models/automate_entrypoints.js');
EntryPoints.update(
{ "onCommands._id": req.body._id },
{
"$pull": {
"onCommands": { "_id": req.body._id }
}
},
function (err, numAffected) { console.log("data:", numAffected) }
);

How to use $in in mongoose reference schema

I have 2 schemas 1st is city and second is pincode. Pincode having reference of city. They both look like this
CITY schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// create a all city list
var allCitySchema = new Schema({
cities: {
type: String
}
}, {collection: 'allcities'});
var allcities = mongoose.model('allcities', allCitySchema);
module.exports = allcities;
Pincode schemas
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var allPincode = new Schema({
city_id: {
type: Schema.ObjectId,
ref: 'allcities'
},
pincode: {
type: String
}
}, {collection: 'pincode'});
var allPincode = mongoose.model('pincode', allPincode);
module.exports = allPincode;
Now the problem is when i tried to fetch all pincode based upon city id for that i tries like this
app.post('/api/getPincodeByCity', function(req, res) {
console.log("In pincode");
var cities_id = [];
cities_id = req.body.cities_id;
console.log(req.body); // { cities_id: '["5597aa08c0a0beb40be128d4","5597aa2bbb18fefc142b6915"]' }
console.log(cities_id);
pincodes.findById( {city_id: { $in: cities_id }}, function(err,pincodeIds){
if(err) res.send(err.message);
res.send(pincodeIds);
res.end('{"success" : "Recieved Successfully", "status" : 200}');
});
});
But it's not working its giving me this error
Cast to ObjectId failed for value "[object Object]" at path "_id"
I also try with find() instead of findById() method but it giving me this error
undefined is not a function
The $in operator is not just "strictly" for querying arrays as that can be done with basically any operator for a singular value.
It's actually a "list of arguments" which evaluates to an $or condition, but with shorter syntax:
var idList = ["559e0dbd045ac712fa1f19fa","559e0dbe045ac712fa1f19fb"];
var pincode = mongoose.model('pincode');
pincode.find({ "city_id": { "$in": idList } },function(err,docs) {
// do something here
});
Which as mentioned is short form for this:
pincode.find(
{
"$or": [
{ "city_id": "559e0dbd045ac712fa1f19fa" },
{ "city_id": "559e0dbe045ac712fa1f19fb" }
]
},
function(err,docs) {
// do something here
}
)
You are getting an error because you are overwriting the "array" definition with a "string" which is what all "request" objects are unless parsed otherwise.
The other reason for the error is you are calling the wrong method. .findById() expects a single argument of the _id for the document. To query other fields use .findOne() or in this case .find() since an $in will possibly match more than one document.

MongoDB to return assoc array of results

My collection has object with the following form
{'id':2, 'name':'john', 'avatar':'img.png'},
{'id':3, 'name':'chriss', 'avatar':'img2.png'}
After i query mongo, i want to get the following results
{'2': {'id':2, 'name':'john', 'avatar':'img.png'}, '3':{'id':3, 'name':'chriss', 'avatar':'img2.png'}}
Is it possible to do this with mongo or do i have to iterate over the results to get this form ?
You could try iterating over the results using the find() cursor's forEach() method as follows :
var obj = {};
db.collection.find({}, {"_id": 0}).forEach(function(doc){
obj[doc.id.toString()] = doc;
});
printjson(obj);
Or using the map() method:
var mapped = db.collection.find({}, {"_id": 0}).map(function(doc){
var obj = {};
obj[doc.id.toString()] = doc;
return obj;
});
printjson(mapped);
Output in both methods:
{
"2" : {
"id" : 2,
"name" : "john",
"avatar" : "img.png"
},
"3" : {
"id" : 3,
"name" : "chriss",
"avatar" : "img2.png"
}
}

Resources