On my localhost/list page, my GET is showing
[{"_id":"5756f1aa64fa4d3104f98f89","mcr":"relationship","info":{"test":"test"}}]
but I would like to only return
[{"info":{"test":"test"}}]
My find function works just fine on the mongo command line and it returns what is expected.:
db.usercollection.find({},{"_id":0,"mcr":0})
However, when called in my JS file, it doesn't filter out the query. I'm using express and monk along with MongoDB. This is my router.get:
router.get('/list', function(req, res) {
var db = req.db;
var collection = db.get('usercollection');
collection.find({},{"_id":0,"mcr":0},function(e,docs){
res.json(docs);
});
});
No errors are thrown and the status code is 200, what could the problem be? I've tried a ton of variations within the find function, and haven't had any luck.
I found the issue, apparently mongo hadn't updated their docs completely. I needed to use {fields: {_id:0}}.
Final code:
router.get('/list', function(req, res) {
req.db.get('usercollection').find({},{fields: {"_id":0,"mcr":0}},function(e,docs){
res.json(docs);
//console.log(docs);
});
});
Related
Hi fellow developers!
I've got this error showing up in my console when I try to save two identical documents in a collection in MongoDB that has nothing to do with the index shown in the error.
Here's the error: E11000 duplicate key error collection: Bohemian.orders index: user.email_1 dup key: { user.email: null }
Now this makes no sense, because I'm trying to save an Order document in a separate collection, which has nothing to do with the user router I had set up previously.
Here is the schema and model code:
const mongoose = require('mongoose');
const orderSchema = new mongoose.Schema({
amountToPay: Number,
});
const Order = mongoose.model("Order", orderSchema);
module.exports.Order = Order;
As shown here, I am only trying to save the amount to be payed into the database in a separate collection.
Here is the router file:
const express = require('express');
const router = express.Router();
const { Order } = require('../models/Order');
router.get("/", async (req, res, next) => {
try {
const orders = await Order.find();
if (orders.length === 0) return res.status(404).send("There are currently no orders");
res.send(orders);
} catch (ex) {
console.error(ex);
next();
}
});
router.post("/", async (req, res, next) => {
try {
const order = new Order({
amountToPay: req.body.amountToPay
});
await order.save();
res.send(order);
} catch (ex) {
console.error(ex);
next();
}
});
module.exports = router;
As you can see there is nothing relative to the error that I'm getting and I have no clue why I'm getting a duplicate user.email = null key , when I haven't made any reference to the User model or router.
Here is the POST call I'm making from POSTMAN to test:
Pretty straight forward, nothing extreme, nothing tangled, right? Well the first ever POST call saves the document in the Database, but from then on I keep getting the same error. The only thing I can take from that is that when I save the first document, Mongo looks for the user.email property when I'm creating the new instance of Order and when it doesnt find it, it creates it with a value of null and then the next document would naturally be a duplicate, hence the error. But I'm confused, because this model and router should not absolutely nothing to do with the user ones.
Here is the error:
So please if anyone can help me understand why MongoDB is screwing with me or where I'm making a mistake, I would really appreciate it.
I found out what the problems was, thanks to Molda:
At some point I had created these indexes, which I'm still unsure when and how, but I did. Which essentially lead to this error, when I tried to save the second document.
A simple quick console log of the indexes in the collection showed that I had that index in there.
const indexes = await Order.collection.getIndexes();
console.log(indexes);
Then I removed them using this method:
await Order.collection.dropIndexes("user.email_1");
And everything worked flawlessly from there.
I hope this helps anyone in this situation in the future and thanks Molda! :)
I'm using Monk and MongoDB to try and get a record by ID populate through the request params but it returns nothing.
I've tried lots of the suggestions on SO but nothing is working, does anyone have any ideas where I'm going wrong?
Here is my code:
router.get('/:id', function(req, res) {
var db = req.db;
var collection = db.get('bugs');
collection.findById(req.params.id, {}, function(e,docs){
res.render('bug', { 'bug': docs });
});
});
And I'm trying to access by going to localhost:3000/bugs/recordidstring
Thanks
I was being an utter idiot and when I was connecting to the DB I was connecting to the wrong one!
Sorry guys, my bad!
I'm using the MEAN stack for a web app. In my controller.js, I have the following:
var refresh3 = function() {
$http.get('/users').success(function(response) {
console.log("I got the data I requested");
$scope.users = response;
$scope.contact3 = "";
});
};
refresh3();
This pulls back every object in the "users" collection from my MongoDB. How could I add parameters to this to bring back, for example, only objects where "name" : "Bob" ? I have tried adding parameters in the '/users' parentheses using:
$http.get('/users', {params:{"name":"Bob"}})
I've also tried variants of that, but no luck. Any help would be appreciated!
If your server is receiving the data
(and it should, as $http.get('/users', {params:{"name":"Bob"}}) is correct)
On server side, make use of the query string:
req.query
like so:
app.get('/users', function(req,res){
if(req.query.name){
db.users.find({"name":req.query.name},function (err, docs) { console.log(docs); res.json(docs); });
}
else{
db.users.find(function (err, docs) { console.log(docs); res.json(docs); });
}
});
WHAT WAS THE ISSUE?
You hinted in your comments that your server was set to respond to the app.get('/users') GET request like so:
db.users.find(function (err, docs) {
// docs is an array of all the documents in users collection
console.log(docs); res.json(docs); }); });
So I believe that your angularjs $http get is correct, and your server is receiving the parameters {"name":"Bob"} as it should;
it just doesn't know what to do with them:
all it is set to do is to return the whole collection in the particular case of a app.get('/users') GET request.
HOW TO CONFIGURE YOUR SERVER FOR REST
You do not have to re-invent the wheel on the server.
Rather, you could consider using a middleware to automate the task (in the present case, the task is to issue a proper MongoDb request when you receive a get query with parameters from the client)
e.g. express-restify-mongoose middleware
I've been trying to figure out why my HTTP Put has not been working after I use it once. When I click a button, I push the current user's id into an array like so:
$scope.currentUser = {
'eventsAttending' = [];
}
$scope.attending = function(event, id){
if($cookieStore.get('token')){
$scope.currentUser = Auth.getCurrentUser();
}
$scope.currentUser.eventsAttending.push(event._id);
$http.put('/api/users/' + $scope.currentUser._id, $scope.currentUser)
.success(function(data){
console.log("Success. User " + $scope.currentUser.name);
});
}
And my HTTP Put function is like so:
var express = require('express');
var controller = require('./user.controller');
var config = require('../../config/environment');
var auth = require('../../auth/auth.service');
router.get('/:id', controller.getEvents);
var router = express.Router();
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
User.findById(req.params.id, function (err, user) {
if (err) { return res.send(500, err); }
if(!user) { return res.send(404); }
var updated = _.merge(user, req.body);
updated.markModified('eventsAttending');
updated.save(function (err) {
if (err) { return res.send(500, err); }
return res.json(200, user);
});
});
};
In my HTML page I have multiple events I can attend, and each event has the button called Attend where I call $scope.attending and the function is called and the HTTP Put occurs. All of this works for the first event I choose to attend. However, when I click the Attend button for another event, I get an error that says:
{"message":"No matching document found.","name":"VersionError"}
And I have no idea why. The error occurs when I try to do updated.save() in the mongoose call and I get res.send(500, err)
I tried to look at http://aaronheckmann.blogspot.com/2012/06/mongoose-v3-part-1-versioning.html to solve the issue as I did some googling but I keep getting an error that says:
Undefined type at `versionKey`
Did you try nesting Schemas? You can only nest using refs or arrays.
Upon adding into my schema:
var UserSchema = new Schema({
versionKey: 'myVersionKey',
...
I also tried to change the .save() function into .update() as someone suggested it online but that seemed to give me even more errors. Any ideas how to fix this? That would be much appreciated!
I think the issue you may be experiencing (as was the case when I was getting this error from a similar action) is that after the first update, the '__v' VersionKey property on the newly updated document has changed, but you might not be updating that property on the object you have in the browser. So when you go to update it again, you're sending the old '__v' VersionKey, (even though you updated the 'eventsAttending' property) and that document conflicts the newer VersionKey. This would assume that the Auth.getCurrentUser(); function returns the whole document object from mongo.
What I did to fix this was simply add delete entity.__v; to delete the old VersionKey from the document before sending it with the request. Better yet, I'd recommend updating the properties your API sends back when returning documents so this issue doesn't happen in the first place.
I have a database on MongoLab. It has several collections. All but one work. One collection is called "selectopts". It has two documents. I can clearly see these two documents.
In my express code I have...
var db = require('mongojs');
db.connect('mongodb://xxxx:xxxx#ds053xxx.mongolab.com:53xxx/rednecks',['selectopts']);
exports.selects = function (req, res) {
db.selectopts.find(function (err, s) {
if (err) return;
res.json(s);
});
};
It always errors at db.selectopts.find..., TypeError: Cannot call method 'find' of undefined. This exact same stupid simple code works fine for four other collections. Why is just this one collection not coming back from MongoLab?
I'm so completely stumped.
EDIT...
Tried db.collection('selectopts').find(... and got this error...
EDIT again...
Here are the two docs in the selectopts collection on MongoLab. Do you see some problem with the docs?...
EDIT x 3...
This is the correct/working mongo connection setup code...
var mongojs = require('mongojs');
var db = mongojs.connect(
'xxx:xxx#ds053xxx.mongolab.com:53xxx/rednecks',
);
See the main difference? (SMFH) :-/
Sometimes when I post at SO I don't receive the exact actual answer from any one reply, but somehow you guys always steer me toward the answer. In this case, it was programmer stupidity. My code at the top of the route js file is wrong. You can see it wrong at the top of this post. I edited and added the correct syntax, which magically got everything working.
To eliminate this type of repetition/syntax/non-DRY bungling, I moved the mongo connection lines into a separate database.js file and require it at the top of the route files. Genius huh?!? :-D
"Thank you" x 100 for all your replies! You always get me back on track :-)
Connect using the following style:
var MongoClient = require('mongodb').MongoClient;
var db;
MongoClient.connect(
'mongodb://xxxx:xxxx#ds053xxx.mongolab.com:53xxx/rednecks',
{auto_reconnect: true},
function(e, database)
{
db = database;
});
exports.selects = function (req, res) {
db.selectopts.find(function (err, s) {
if (err) return;
res.json(s);
});
};