When I make a post REQUEST in thunder client I can't get my data back in response but I get 500 internal server error, this is the error that I got the posting request in thunder client or postman
{
"code": 79,
"codeName": "UnknownReplWriteConcern",
"errInfo": {
"writeConcern": {
"w": "majority;",
"wtimeout": 0,
"provenance": "clientSupplied"
}
},
"result": {
"n": 1,
"opTime": {
"ts": {
"$timestamp": "7022899934215012355"
},
"t": 99
},
"electionId": "7fffffff0000000000000063",
"ok": 1,
"writeConcernError": {
"code": 79,
"codeName": "UnknownReplWriteConcern",
"errmsg": "No write concern mode named 'majority;' found in replica set configuration",
"errInfo": {
"writeConcern": {
"w": "majority;",
"wtimeout": 0,
"provenance": "clientSupplied"
}
}
},
"$clusterTime": {
"clusterTime": {
"$timestamp": "7022899934215012355"
},
"signature": {
"hash": "/gnrM/bYkyRYi4XXXmEnkaLJJpg=",
"keyId": {
"low": 1,
"high": 1620408145,
"unsigned": false
}
}
},
"operationTime": {
"$timestamp": "7022899934215012355"
}
}
}
I have faced the same problem and put this code which contain ( writeConcern )in my schema and it works
const schema = new Schema({
name: String
}, {
writeConcern: {
w: 'majority',
j: true,
wtimeout: 1000
}
});
another thing I did I removed a single quotes that was around my db url
checkout this https://pretagteam.com/question/mongowriteconcernerror-no-write-concern-mode-named-majority-found-in-replica-set-configuration
I'm trying to update the values of my payments array objects
{
"balance": 109610,
"gifts": [],
"orders": [],
"payments": [{
"isPaid": 0,
"status": "Pending",
"address": "3KsdQbmADyz1KNN7qqX1yZcMXBbfFCm31r",
"date": 1624057559970
}, {
"isPaid": 0,
"status": "Pending",
"address": "3FYQK6YiAaL8fEbDWaXYw38CJN3K2y5dPD",
"date": 1624058531601
}],
"isVendedor": false,
"isAdmin": true,
"createdAt": {
"$date": "2021-06-17T21:10:15.020Z"
},
"username": "teste",
"email": "teste#teste.com",
"password": "$2a$10$qUNkorDuvbf.AYLTvjNc4ebKyNgLa7L9NoTBwAIV8.BfN51umaD9O",
"__v": 3
}
First, I look for the object of the user who made a request to my server
const userPayment = await User.find({"payments.address": notification.address}).exec();
Then I go through the user object and find it until I find the position where I find notification.address again
userPayment.forEach((AllPayments, index) => {
AllPayments.payments.forEach((payment, index) => {
if (payment.address == notification.address) {
if (payment.isPaid || payment.status != "Pending")
return res.json({
success: false,
error: "Payment Already Processed!",
});
const valueToDeposit = Math.round(notification.fiat_amount);
console.log(
userPayment[0].payments[index].isPaid,
userPayment[0].payments[index].status
);
// Set payments[index].isPaid = true
// Set payments[index].status = "Paid"
});
});
So I tried to make these 3 ways and none of them was successful.
userPayment[0].balance += valueToDeposit; // this works when save() is triggered
userPayment[0].payments[index].isPaid = 1; // this doesnt works when save() is triggered
userPayment[0].payments[index].status = "Paid"; // this doesnt works when save() is triggered
userPayment[0].updateOne({"payments.address": notification.address}, { $set: { "payments.$.isPaid": 1,"payments.$.status":"Paid" } },(err, result) => { console.log(err, result); }); this doesnt works
userPayment[0].save()
This is my controller file locations.js
var mongoose = require('mongoose');
var Loc = mongoose.model('location');
module.exports.locationsListByDistance = function(req, res) {
var lng = parseFloat(req.query.lng);
var lat = parseFloat(req.query.lat);
var point = {
type: "Point",
coordinates: [lng, lat]
};
var geoOptions = {
spherical: true,
maxDistance: 1000
};
Loc.geoNear(point, geoOptions, function (err, results, stats) {
console.log(results);
});
};
My model file locations.js
var mongoose = require('mongoose');
var reviewSchema = new mongoose.Schema({
author: String,
rating: {
type: Number,
required: true,
min: 0,
max: 5
},
reviewText: String,
createdOn: {
type: Date,
"default": Date.now
}
});
var openingTimeSchema = new mongoose.Schema({
days: {
type: String,
required: true
},
opening: String,
closing: String,
closed: {
type: Boolean,
required: true
}
});
var locationSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
address: String,
rating: {
type: Number,
"default": 0,
min: 0,
max: 5
},
facilities: [String],
// Always store coordinates longitude, latitude order.
coords: {
type: [Number],
index: '2dsphere'
},
openingTimes: [openingTimeSchema],
reviews: [reviewSchema]
});
mongoose.model('location', locationSchema, 'locations');
Whenever I run http://localhost:3000/api/locations?lng=-0.9690884&lat=51.455041 I get error geoNear is not a function
TypeError: Loc.geoNear is not a function
at module.exports.locationsListByDistance (/home/shackers/Projects/mean/loc8r/app_api/controllers/locations.js:51:7)
at Layer.handle [as handle_request] (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/layer.js:95:5)
at next (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/route.js:137:13)
at Route.dispatch (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/layer.js:95:5)
at /home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:281:22
at Function.process_params (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:335:12)
at next (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:174:3)
at router (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:317:13)
at /home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:335:12)
at next (/home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:275:10)
at /home/shackers/Projects/mean/loc8r/node_modules/express/lib/router/index.js:635:15
This are versions of dependencies i am using:
node : 8.9.3 npm : 5.5.1 express : 4.15.5 mongoose : 5.0.0
mongoDb : 3.6.1
router.get('/', () => {
Loc.aggregate([
{
$geoNear: {
near: 'Point',
distanceField: "dist.calculated",
maxDistance: 100000,
spherical: true
}
}
]).then(function(err, results, next){
res.send();
}).catch(next);
});
Ref:- https://docs.mongodb.com/manual/reference/command/geoNear/
This error is happening because .geoNear used to be supported, but is no longer supported as of Mongoose 5, which uses the Node MongoDB v3 driver.
The issue is documented in the Migrating to Mongoose 5 document, which in turn links to the MongoDB 3 drive release notes which provides this statement about recommend replacements:
The functionality of the geoNear command is duplicated elsewhere in the language, in the $near/$nearSphere query operators on unsharded collections, and in the $geoNear aggregation stage on all collections.
Effectively, the official docs are endorsing kind of use of $geoNear documented in other answers.
I'm having the exact same problem and I've abandoned the approach I was using before (which looks like you were having too). The following is an alternative that does not throw an error and should give you the same result you were after using Loc.geoNear:
Loc.aggregate(
[
{
'$geoNear': {
'near': point,
'spherical': true,
'distanceField': 'dist',
'maxDistance': 1000
}
}
],
function(err, results) {
// do what you want with the results here
}
)
Apparently I'm in the same book (Getting Mean, Manning) and running into roughly the same issues. This seems to work for me:
var mongoose = require('mongoose');
var Loc = mongoose.model('Location');
var sendJSONresponse = function(res, status, content) {
res.status(status);
res.json(content);
};
var theEarth = (function() {
console.log('theEarth');
var earthRadius = 6371; // km, miles is 3959
var getDistanceFromRads = function(rads) {
return parseFloat(rads * earthRadius);
};
var getRadsFromDistance = function(distance) {
return parseFloat(distance / earthRadius);
};
return {
getDistanceFromRads: getDistanceFromRads,
getRadsFromDistance: getRadsFromDistance
};
})();
/* GET list of locations */
module.exports.locationsListByDistance = function(req, res) {
console.log('locationsListByDistance:');
var lng = parseFloat(req.query.lng);
var lat = parseFloat(req.query.lat);
var maxDistance = parseFloat(req.query.maxDistance);
var point = {
type: "Point",
coordinates: [lng, lat]
};
console.log('point: ' + point)
var geoOptions = {
spherical: true,
maxDistance: theEarth.getRadsFromDistance(maxDistance),
num: 10
};
console.log('geoOptions: ' + geoOptions);
if ((!lng && lng!==0) || (!lat && lat!==0) || ! maxDistance) {
console.log('locationsListByDistance missing params');
sendJSONresponse(res, 404, {
"message": "lng, lat and maxDistance query parameters are all required"
});
return;
} else {
console.log('locationsListByDistance running...');
Loc.aggregate(
[{
'$geoNear': {
'near': point,
'spherical': true,
'distanceField': 'dist.calculated',
'maxDistance': maxDistance
}
}],
function(err, results) {
if (err) {
sendJSONresponse(res, 404, err);
} else {
locations = buildLocationList(req, res, results);
sendJSONresponse(res, 200, locations);
}
}
)
};
};
var buildLocationList = function(req, res, results) {
console.log('buildLocationList:');
var locations = [];
results.forEach(function(doc) {
locations.push({
distance: doc.dist.calculated,
name: doc.name,
address: doc.address,
rating: doc.rating,
facilities: doc.facilities,
_id: doc._id
});
});
return locations;
};
returns a result list similar to such:
[
{
"distance": 0,
"name": "Rathaus",
"address": "Markt",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e503e"
},
{
"distance": 61.77676881925853,
"name": "Haus Löwenstein",
"address": "",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e5045"
},
{
"distance": 63.03445976427102,
"name": "Goldener Schwan",
"address": "Markt 37",
"rating": 0,
"facilities": [
"restaurant"
],
"_id": "5a9366517775811a449e5052"
},
{
"distance": 66.60375653163021,
"name": "Klein Printenbäckerei",
"address": "Krämerstraße 12",
"rating": 0,
"facilities": [
"supermarket"
],
"_id": "5a9366517775811a449e504d"
},
{
"distance": 74.91278395082011,
"name": "Couven-Museum",
"address": "Hühnermarkt 17",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e5042"
},
{
"distance": 132.2939512054143,
"name": "Cathedral Treasury",
"address": "Johannes-Paul-II.-Straße",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e503d"
},
{
"distance": 152.11867357742042,
"name": "Aachen Cathedral",
"address": "Domhof 1",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e503c"
},
{
"distance": 155.92015153163268,
"name": "International Newspaper Museum",
"address": "Pontstraße 13",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e5040"
},
{
"distance": 175.0857109968383,
"name": "Nobis Printen",
"address": "Münsterplatz 3",
"rating": 0,
"facilities": [
"supermarket"
],
"_id": "5a9366517775811a449e504c"
},
{
"distance": 179.32348875834543,
"name": "Grashaus",
"address": "Fischmarkt",
"rating": 0,
"facilities": [
"museum"
],
"_id": "5a9366517775811a449e5044"
},
{
"distance": 189.8675948747873,
"name": "Maranello",
"address": "Pontstraße 23",
"rating": 0,
"facilities": [
"restaurant"
],
"_id": "5a9366517775811a449e5057"
},
{
"distance": 198.2239741555585,
"name": "Carlos I",
"address": "Rennbahn 1",
"rating": 0,
"facilities": [
"restaurant"
],
"_id": "5a9366517775811a449e5055"
}
]
Not sure how accurate it is - got a list of addresses loaded and not 100% sure what's close to what in the random mess... but it returns a list and I'll test correctness somehow at some point.
I found the solution. Just downgrade mongoose and install version 4.9.1. Latest release of mongoose does not support Loc.geoNear
npm remove mongoose
npm install mongoose#4.9.1
More straightforward IMO, than the previous two answers in the Grider's course is:
index(req, res, next) {
const { lng, lat } = req.query;
Driver.find({
'geometry.coordinates': {
$nearSphere: {
$geometry: {
type: 'Point',
coordinates:[parseFloat(lng), parseFloat(lat)]
},
$maxDistance: 200000,
},
}
})
.then(drivers => res.send(drivers))
.catch(next);
}
This is in the spirit of the original definition he gives and uses the new functions which do the same thing as the old geoNear, except they've split out the spherical and non-spherical versions now. You'll need:
beforeEach((done) => {
const { drivers } = mongoose.connection.collections;
drivers.drop()
.then(() => drivers.createIndex({ 'geometry.coordinates': '2dsphere' }))
.then(() => done())
.catch(() => done());
};
In the test helper as mentioned before.
I think you're looking for this, please correct me if there is mistake there.
module.exports.locationsListBydistance = function (req, res) {
var lng = parseFloat(req.query.lng);
var lat = parseFloat(req.query.lat);
Loc.aggregate(
[{
$geoNear: {
'near': {'type':'Point', 'coordinates':[lng, lat]},
'spherical': true,
'maxdistance': theEarth.getRadsFromDistance(20),
'num':10,
'distanceField': 'dist'
}
}
], function(err, results) {
var locations = [];
console.log(results);
results.forEach(function (doc) {
locations.push({
distance: theEarth.getDistanceFromRads(doc.dist),
name: doc.name,
address: doc.address,
facilities: doc.facilities,
rating: doc.rating,
_id: doc._id
});
});
sendJsonResponse(res, 200, locations);
});
};
router.get('/',function(req,res,next){
Loc.aggregate([
{
$geoNear: {
near: {type:'Point', coordinates:[parseFloat(req.query.lng), parseFloat(req.query.lat)]},
distanceField: "dist.calculated",
maxDistance: 1000,
spherical: true
}
}
]).then(function(Locs){
res.send(Locs)
})
})
Model.geoNear() has been removed because the MongoDB driver no longer supports it
Model.geoNear() has been removed because the MongoDB driver no longer supports it, so you should use the aggregation method for example :
for mongoose v4.2:
my code was like this :
Modal.geoNear(
{type: 'Point', coordinates: [parseFloat(req.query.lng), parseFloat(req.query.lat)]},
{maxDistance: 100000, spherical: true}
)
.then(results => {
res.send(results);
})
for the latest mongoose version :
the code is :
Modal.aggregate([{
$geoNear: {
near: {
type: 'Point',
coordinates: [parseFloat(req.query.lng), parseFloat(req.query.lat)]
},
distanceField: 'distance',
maxDistance: 100000,
spherical: true
}
}])
.then(results => {
res.send(results);
})
Hope i answer or solve your problem, happy coding :D
The answer given by user : phao5814 is quite right I tried it out and must say It worked out well for me
index(req, res, next)
{
const { lng, lat } = req.query;
Driver.aggregate([
{
'$geoNear': {
"near": { 'type': 'Point',
'coordinates': [parseFloat(lng), parseFloat(lat)] },
"spherical": true,
"distanceField": 'dist',
"maxDistance": 200000
}
}
])
.then(drivers => res.send(drivers))
.catch(next);
}
I try to use the ember precompiler as described here. I just want to precompile in my development process and deploy everything to my production environment where there is no node.js server.
When I include the generated js - files for all my compiled templates I get these errors in console: SyntaxError: missing declaration after 'export' keyword
This is a example of my fu.js - file, compiled from fu.hbs.
export default Ember.HTMLBars.template((function() {
return {
meta: {
"revision": "Ember#1.13.3",
"loc": {
"source": null,
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
}
},
arity: 0,
cachedFragment: null,
hasRendered: false,
buildFragment: function buildFragment(dom) {
var el0 = dom.createDocumentFragment();
var el1 = dom.createTextNode("Hello Fufu");
dom.appendChild(el0, el1);
return el0;
},
buildRenderNodes: function buildRenderNodes() { return []; },
statements: [
],
locals: [],
templates: []
};
}()));
Shouldn't be there a identifier for my hbs? Like "fu.hbs", how are the precompiled templates added to my ember application? Do I just have to reference the js-files inside my index.html with the same name as the templates?
If everything would work, do I still have to put the following stuff into my index.html?
<script type="text/x-handlebars" data-template-name="fu" id="fu">
Hello Fufu
</script>
I found the solution now, without docs...
After precompiling the templates I had to add every Template to the Ember.TEMPLATES[] array so the code now looks like:
Ember.TEMPLATES["fu"] = Ember.HTMLBars.template((function() {
return {
meta: {
"revision": "Ember#1.13.3",
"loc": {
"source": null,
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 10
}
}
},
arity: 0,
cachedFragment: null,
hasRendered: false,
buildFragment: function buildFragment(dom) {
var el0 = dom.createDocumentFragment();
var el1 = dom.createTextNode("Hello Fufu");
dom.appendChild(el0, el1);
return el0;
},
buildRenderNodes: function buildRenderNodes() { return []; },
statements: [
],
locals: [],
templates: []
};
}()));
The <script type="text/x-handlebars" data-template-name="fu" id="fu"> - Elements in Index - file can be removed.
Should this work? I am trying to remove a single subdocument (following) from a document (this) in the UserSchema model.
UserSchema.methods.unFollow = function( id ) {
var user = this
return Q.Promise( function ( resolve, reject, notify ) {
var unFollow = user.following.pull( { 'user': id } )
console.log( unFollow )
user.save( function ( error, result ) {
resolve( result )
})
})
}
These are the schemas:
var Follows = new mongoose.Schema({
user: String,
added: Number
})
var UserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
unique: true
},
following: [ Follows ]
})
user-controller.js
/*
Unfollow user.
*/
exports.unFollow = function ( req, res ) {
User.findOne( { token: req.token }, function ( error, user ) {
user.unfollow( req.body.id )
.onResolve( function ( err, result ) {
if ( err || !result ) return res.status( 500 ).json( "User could not be unfollowed." )
return res.status( 200 ).json( "User unfollowed." )
})
})
}
user-model.js
/*
Unfollow a user.
*/
UserSchema.method( 'unfollow', function unfollow ( id ) {
this.following.pull( { user: id } )
return this.save()
})
You generally assign methods using the method function:
UserSchema.method('unFollow', function unFollow(id) {
var user = this;
user.following.pull({_id: id});
// Returns a promise in Mongoose 4.X
return user.save();
});
Also, as noted, you don't need to use Q as save will return a mongoose promise.
UPDATE: Mongoose's array pull method will work with matching primitive values but with subdocument objects it will only match on _id.
UPDATE #2: I just noticed your updated question shows that your controller is doing a lookup first, modifying the returned document and then saving the document back to the server. Why not create a static rather than a method to do what you want? This has the added bonus of being a single call to the DB rather than two per operation.
Example:
UserSchema.static('unfollow', function unfollow(token, id, cb) {
var User = this;
// Returns a promise in Mongoose 4.X
// or call cb if provided
return User.findOneAndUpdate({token: token}, {$pull: {follows: {user: id}}}, {new: true}).exec(cb);
});
User.unfollow(req.token, req.body.id).onResolve(function (err, result) {
if (err || !result) { return res.status(500).json({msg: 'User could not be unfollowed.'}); }
return res.status(200).json({msg: 'User unfollowed.'})
});
Bonus follow static:
UserSchema.static('follow', function follow(token, id, cb) {
var User = this;
// Returns a promise in Mongoose 4.X
// or call cb if provided
return User.findOneAndUpdate({token: token}, {$push: {follows: {user: id}}}, {new: true}).exec(cb);
});
User.follow(req.token, req.body.id).onResolve(function (err, result) {
if (err || !result) { return res.status(500).json({msg: 'User could not be followed.'}); }
return res.status(200).json({msg: 'User followed.'})
});
NOTE: Used in "mongoose": "^5.12.13".
As for today June 22nd, 2021, you can use $in and $pull mongodb operators to remove items from an array of documents :
Parent Document :
{
"name": "June Grocery",
"description": "Some description",
"createdDate": "2021-06-09T20:17:29.029Z",
"_id": "60c5f64f0041190ad312b419",
"items": [],
"budget": 1500,
"owner": "60a97ea7c4d629866c1d99d1",
}
Documents in Items array :
{
"category": "Fruits",
"bought": false,
"id": "60ada26be8bdbf195887acc1",
"name": "Kiwi",
"price": 0,
"quantity": 1
},
{
"category": "Toiletry",
"bought": false,
"id": "60b92dd67ae0934c8dfce126",
"name": "Toilet Paper",
"price": 0,
"quantity": 1
},
{
"category": "Toiletry",
"bought": false,
"id": "60b92fe97ae0934c8dfce127",
"name": "Toothpaste",
"price": 0,
"quantity": 1
},
{
"category": "Toiletry",
"bought": false,
"id": "60b92ffb7ae0934c8dfce128",
"name": "Mouthwash",
"price": 0,
"quantity": 1
},
{
"category": "Toiletry",
"bought": false,
"id": "60b931fa7ae0934c8dfce12d",
"name": "Body Soap",
"price": 0,
"quantity": 1
},
{
"category": "Fruit",
"bought": false,
"id": "60b9300c7ae0934c8dfce129",
"name": "Banana",
"price": 0,
"quantity": 1
},
{
"category": "Vegetable",
"bought": false,
"id": "60b930347ae0934c8dfce12a",
"name": "Sombe",
"price": 0,
"quantity": 1
},
Query :
MyModel.updateMany(
{ _id: yourDocumentId },
{ $pull: { items: { id: { $in: itemIds } } } },
{ multi: true }
);
Note: ItemIds is an array of ObjectId. See below :
[
'60ada26be8bdbf195887acc1',
'60b930347ae0934c8dfce12a',
'60b9300c7ae0934c8dfce129'
]