mongoose returning duplicate results - node.js

Pretty new to mongo and mongoose.
I have
var mongoose = require('mongoose'),
errorHandler = require('./errors'),
ClientSummary = mongoose.model('ClientSummary');
exports.list = function(req, res) { ClientSummary.find().sort('-LastName').exec(function(err, clients) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
console.log(clients);
res.jsonp(clients);
}
});
};
this returns double results for each client
I copied this from the console
[ { _id: '_?\u0007Z?WM???3\u0016?\u0017',
ArchivedDate: Sun Dec 31 0 18:00:00 GMT-0600 (Central Standard Time),
ArchiveDate: Sat Nov 08 2014 17:18:55 GMT-0600 (Central Standard Time),
Archived: false,
Phone: null,
EmailAddress: 'test#test.com',
LastName: 'test',
FirstName: 'test' },
{ _id: '??\u0002otsF???\u000fF\u0010\u0019\n',
ArchivedDate: Sun Dec 31 0 18:00:00 GMT-0600 (Central Standard Time),
ArchiveDate: Sat Nov 08 2014 17:18:55 GMT-0600 (Central Standard Time),
Archived: false,
Phone: null,
EmailAddress: 'test#test.com',
LastName: 'test',
FirstName: 'test' } ]
I get this from a query
db.clients.find()
{ "_id" : BinData(4,"U/UnaPQyRxqtc1iPJP7Lyw=="), "Contact" : { "FirstName" : "test", "LastName" : "test", "EmailAddress" : "test#test.com", "Phone" : null, "PhoneSecondary" : null }, "Address" : null, "Source" : null, "SourceNotes" : "asdf", "Archived" : false, "ArchivedDate" : ISODate("0001-01-01T00:00:00Z"), "StartDate" : ISODate("0001-01-01T00:00:00Z") }
any thoughts would be greatly appreciated
Thanks,
Raif

I do not see why you are saying that you have duplicate results in the first query. The _ids are different, so, it looks like there are two different objects.
Further, I also think that the second query that you have refers to a different collection; i.e. clients, while the first query refers to the collection clientsummary.
For example, use the mongo shell, connect to the db *, and try the following two:
> show collections
If I am right, you have both clients and clientsummary as collections in your db. Then, also try
> db.clientsummary.count()
This should return 2.
Note, that it might be the case that you have clientSummary instead of clientsummary as collection in your db, or even clientsummarys/clientSummarys or clientsummaries/clientSummaries as mongo/mongoose will use the plural for the collection and an s is usually attached in the end of the word referring to the collection. Just use the right name.
(*) You can connect to the db mydb (where the collections you are referring to can be found) using the command:
$ mongo --shell localhost/mydb
(Assuming you have mydb on localhost.)

Related

How to update the details in an array on post in MongoDB?

Although its printing the 'success' in console but i am unable to see the changes after clicking on post update.
User.update( { email:req.user.email },
{ $set: {
"Addtasks.$[].topic": req.body.topic,
"Addtasks.$[].words": req.body.words,
"Addtasks.$[].keywords": req.body.keywords,
"Addtasks.$[].website": req.body.website,
"Addtasks.$[].otherdetails": req.body.otherdetails,
"Addtasks.$[].exampleRadios": req.body.exampleRadios
} },function (error, success) {
if (error) {
console.log(error);
} else {
res.redirect('/status');
console.log('success');
}
} )
My json array file:
[
{
"Date" : "Mon Aug 03 2020 03:30:17 GMT+0530 (India Standard Time)",
"exampleRadios" : "option1",
"otherdetails" : "haha great!",
"website" : "nmbn.com",
"keywords" : "anxiety disorders for children, anxiety disorders for adults",
"words" : 456,
"topic" : "How to fight anxiety",
"_id" : ObjectId("5f273771ddff850558b1e049")
}
]
Did you checked the db if it's updated? Because if you using native mongodriver, update will not return document itself, you have to use findOneAndUpdate. Second thing, findOneAndUpdate will not return updated document, but old one (dunno why they configured it like this), you have to use options = { returnOriginal: false } (default is true).

Speed up Slow Mongo / Mongoose Query

I have a the following model and indexes:
var mySchema = new Schema({
page: String,
date: Date,
data: Object,
_page: {
type: Schema.Types.ObjectId,
ref: 'Page'
},
});
mySchema.index({_page: 1, date: 1 }, {unique: true});
And this query:
mySchema.find({
_page: page._id,
date: {
$gte: date1,
$lt: date2
}
})
.sort({
date: 1
})
.exec((err, result) => {
console.log(result);
})
And it logs out like this:
myschema.find({ date: { '$gte': new Date("Thu, 16 Nov 2017 23:00:00 GMT"), '$lt': new Date("Thu, 14 Dec 2017 23:00:00 GMT") }, _page: ObjectId("5a57b30bf54be100c315f2f5") }, { sort: { date: 1 }, fields: {} })
And it takes about 1 second to return ~30 results from a table with about 4000 documents and ~60mb.
DB is a replica cluster on mlab, query speed is pretty similar weather I connect from localhost or my server (db and server in w-europe)
Is there any way to speed this up? Am I indexing or querying wrong?
Using lean() method can improve the performance of find query in mongoose. The reason for it is that using this function returns plain Javascript objects instead of extra Mongoose methods like save function, getters and setters. If you want to check the performance difference of a plain Javascript object and Mongoose Object, you can visit this link
However, you can take advantage of it for only read operations. So, if its just find operation, you can use lean().
mySchema.find(...).lean().exec(function(err, docs) {
...
});

angular/express api/mongodb update issue

working with a full MEAN stack.
trying to write data to a "notes" array in my mongodb document id #1.
mongo document:
> db.contacts.find().pretty()
{
"_id" : ObjectId("5a294af85e96746421bf35f1"),
"id" : 1,
"type" : "dealer",
"name" : "ken yoder",
"company" : "kens sales",
"phone" : "817-403-9767",
"notes" : [
{
"date" : "Thu Dec 07 2017 08:15:37 GMT-0600 (CST)",
"by" : "#me",
"note" : "this is a note"
},
{
"date" : "Thu Dec 07 2017 08:16:31 GMT-0600 (CST)",
"by" : "#donny",
"note" : "bla bla bla mumford and sons"
},
{
"date" : "Thu Dec 07 2017 08:34:03 GMT-0600 (CST)",
"by" : "#ken",
"note" : "test with another note"
},
{
"date" : "Thu Dec 07 2017 08:34:29 GMT-0600 (CST)",
"by" : "#ken",
"note" : "test with another notey note note"
}
],
"setNotes" : {
"date" : "Thu Dec 07 2017 10:52:09 GMT-0600 (CST)",
"by" : "#kale",
"note" : "hhsdihufiudhsiuhdshuifds"
}
}
express code:
app.get('/newNote/:noteFor/:noteCount/:noteBy/:note/', function (req, res) {
var setNotes = "notes."+req.params.noteCount;
db.collection('contacts').update({ id:req.params.noteFor }, { $set: { setNotes : {date: Date(), by: req.params.noteBy, note: req.params.note} }}, function(err, res) {
if (err) throw err;
console.log("notefor: "+req.params.noteFor+" noteCount: "+setNotes+" noteBy: "+req.params.noteBy+" note: "+req.params.note);
console.log(res.result.nModified + " for " + req.params.noteFor + " updated");
});
});
if i run this code as it sits, i get nothing, no insert, no errors.
- if i change the update id from "req.params.id" to "1", i get an insert but...
- instead of using my "setNotes" variable (which outputs "notes.4") for the $set identifier, it created a new object called "setNotes".
API URL: /newNote/1/4/#kale/this is a note test
This will just add a new document everytime to notes array:
db.collection('contacts').update({ id:req.params.noteFor }, {
$push: {
notes : {date: Date(), by: req.params.noteBy, note: req.params.note}
}
}, function(err, res) {
//code
}
first read express api basics, http://expressjs.com/en/4x/api.html. from question there is noting in req.params.id , instead of id req.params contain four keys (noteFor, noteCount, noteBy and note ). also you override res varible by result of query notice function(err, res) {.........
db.collection('contacts').update(
{ id:req.params.id },
{ $set:
{ setNotes : {date: Date(), by: req.params.noteBy, note: req.params.note} }
},
{
// if noting found then stop create new document with values of $set
upsert:false
// result should be updated document
new:true
},
function(err, result) {
console.log(err, result)
})

Returned Mongoose id different format than MongoDB shell results?

Clearly there is something I'm not understanding here. I perform a Model.findOne() query, followed by a Model.find() query based on the findOne() result.
The document IDs from the Model.find() query look like they're in a different format than when I query the same documents directly from the Mongo shell. I've Googled for an hour, but no luck. What am I missing??
Model.find() results...
{ _id: ObjectID { _bsontype: 'ObjectID', id: 'W_?àÅÜY¼-íbO' }, // <- Problem
salt: 'ULRtWgj0qgblPRbSPwTe4A==',
displayName: 'test tester',
provider: 'local',
username: 'tester',
created: Tue Jun 14 2016 06:36:48 GMT+0200 (Romance Daylight Time),
roles: [ 'user' ],
profileImageURL: 'modules/users/client/img/profile/default.png',
referrers: { level1: ObjectID { _bsontype: 'ObjectID', id: 'W^_ó 5IE\u0013
N\u0010c' } }, // <- Also problem
password: 'jXpp+RJIegHFKD50sL2aOlOUhE0rvYtSJZIDB244SDIw93yrbuFCTUJK3SZIs3F
w0DdHOUzlQoLQwTGEcF67Kg==',
email: 'test#example.com',
lastName: 'tester',
firstName: 'test',
__v: 0
}
Mongo Shell Results
{
"_id" : ObjectId("575f89e0c5dc59bc2ded62d5"), // <- This is different!
"salt" : "ULRtWgj0qgblPRbSPwTe4A==",
"displayName" : "test tester",
"provider" : "local",
"username" : "tester",
"created" : ISODate("2016-06-14T04:36:48.130Z"),
"roles" : [
"user"
],
"profileImageURL" : "modules/users/client/img/profile/default.png",
"referrers" : {
"level1" : ObjectId("575ebef32035ccc8134e1063") // <- This too!
},
"password" : "jXpp+RJIegHFKD50sL2aOlOUhE0rvYtSJZIDB244SDIw93yrbuFCTUJK3S
ZIs3Fw0DdHOUzlQoLQwTGEcF67Kg==",
"email" : "test#example.com",
"lastName" : "tester",
"firstName" : "test",
"__v" : 0
}
>
Can anyone explain to me what concept I'm missing? Most of my find queries are just fine...this is the first time I've encountered this. Thanks in advance.
OK, this is going to sound really stupid, but in my Mongoose.find() results, instead of getting the id with something like results.id or results._id, I got it to match the strangely formatted id with results._id.id (since the _id itself is an object with an id value).
Seems hacky to me, but it works. So now I have something like:
id = results._id.id || results.id;
Seems super weird, but it works.

Query model against value within a list

When I query a user from its email:
User.findOne({email: 'a#a.com'}).done(function(err, u){console.log(u.sessionTokens);})
I got its tokens list:
[ { token: '8dfe6aa0-2637-4b3f-9a3c-3ae8dc225b77',
issuedAt: Tue Jan 14 2014 14:40:22 GMT+0100 (CET) } ]
But when I query a token within this list it does not retrieve the user:
User.findOne({'sessionTokens.token':'8dfe6aa0-2637-4b3f-9a3c3ae8dc225b77'}).done(function(err, u){console.log(u);})
=> undefined
Any ideas ?
Does the User.findOne({'sessionTokens.token':'8d...77'}) is a correct query ?
EDIT
My User model is something like:
module.exports = {
schema: true,
attributes: {
email: {
type: 'email',
required: true
},
encryptedPassword: {
type: 'string'
},
sessionTokens: {
type: 'array'
},
...
}
}
sessionToken is an attribute of type Array. This array contains several object like:
{ token: '8dfe6aa0-2637-4b3f-9a3c-3ae8dc225b77',
issuedAt: Tue Jan 14 2014 14:40:22 GMT+0100 (CET) }
EDIT
I've tested with mongo-sails instead of mongo-disk, this is working fine but as Chad pointed this out, it depends of the adapter used.
With the help of robdubya & sfb_ in #sailsjs#freenode, we discussed a solution for this a bit. The answer depends on the adapter you are using. The adapter that I am most familiar with is the mysql adapter, and in that adapter, the 'array' attribute type gets serialized to the database as a JSON string. So in that case, using the 'contains' modifier on the query of the model would allow you to find the record you are looking for:
var criteria = {
sessionToken: {
contains: '8dfe6aa0-2637-4b3f-9a3c-3ae8dc225b77'
}
};
User.findOne(criteria).done(function (err, user) {
...
});

Resources