vadimdemedes / mongorito Goto Github PK
View Code? Open in Web Editor NEW🍹 MongoDB ODM for Node.js apps based on Redux
🍹 MongoDB ODM for Node.js apps based on Redux
Would you mind upgrading monk to 1.0.0?
It appears that it would fix this annoying little thing when using iojs:
js-bson: Failed to load c++ bson extension, using pure JS version
Hi I am trying to set the collection name by defining the "collection" property on the class. My code looks like this:
class Abc extends Model {
collection: 'collectionName';
}
collectionName is being ignored
What if I want to get some particular fields from model?
I am trying to find a document in a mongodb collection from two properties. Example:
class Session extends Model {
getCollection() {
return 'sessions';
}
}
var sessions = yield Session.where(
{ status: 'active' , owner: 'mine'} //by default is applying 'or'
).find();
I have tried doing (mongo driver style)
var sessions = yield Session.where(
{ $and: [
{ status: 'active' },
{ owner: 'mine' }
]}).find();
but I think it is not supported.
Is there a way to achieve with this library?
Thanks
Is there any chance to expose MongoDB objects from mongorito?
In utils you get them from mongoskin: https://github.com/vdemedes/mongorito/blob/master/lib/util.js#L5 but in my code it will be look like:
var ObjectID = require('mongorito/node_modules/monk/node_modules/mongoskin').ObjectID;
This is far beyond good path for require - can it be like this (ideal):
var ObjectID = require('mongorito').ObjectID;
P.s. Thanks for awesome module 🐶
How would I access the current model state as a JSON object? (I'm using Joi to handle validation). Basically, I need something like this:
* validate (next) {
let schema = {
title: joi.string()
};
let currentState = {
title: this.get('title')
};
joi.validate(schema, object, {}, function (err) {
if (err) throw err;
yield next;
});
}
Does this look correct?
$ npm install mongorito --save
npm WARN unmet dependency /Developer/Work/oauth-jwt-server/node_modules/mongorito/node_modules/monk/node_modules/mongodb requires bson@'~0.2' but will load
npm WARN unmet dependency /Developer/Work/oauth-jwt-server/node_modules/mongorito/node_modules/bson,
npm WARN unmet dependency which is version 0.3.2
I have iojs 2.4.0
my package.josn
"dependencies": {
"koa": "^0.21.0",
"koa-bodyparser": "^2.0.1",
"koa-jwt": "^1.1.1",
"koa-router": "^5.1.2",
"mongorito": "^1.3.4"
}
Hi there,
I just started using this library and wanted to know if there's a way to execute a function before a query is sent to the database? My use case is that the data in the database is encrypted and I need to encrypt the query object before sending it to the database.
Thanks.
Hi,
I am quite new to node AND mongo, please be patient :)
I am currently in the process of rewriting a webapp's persistence using mongorito. So far I like it quite a lot.
But I need to do things like add comments to an issue, or add followers. These are represented in my schema as arrays of ids or arrays of objects inside the main document.
It used to be implemented using the native mongo $push
keywords, like this:
db.discussion.update(
{ 'discussion_id': discussion_id },
{ '$push': { 'comments': {
'posted': datetime.utcnow(),
'author': author_info,
'text': comment_text } } } );
Using Mongorito, I could not find an equivalent to this construct. The workaround is to load the whole parent (discussion
in this example), add the comment or follower, and finally save the whole object again. This is not optimal. 2 DB hits instead of one, and potentially loading a big object just to add a single id in an array.
What would you recommend instead ? Is there support for this kind of operations built into Mongorito ?
Use get-value to get/set attributes via paths.
I need increment field value use mongo $inc
Should there be the $inc
in the mongorito?
What do you think about this:
var post = yield Post.findById(postId);
yield post.inc({comments: 1});
use:
* inc(increment) {
var collection = this._collection;
var id = this.attributes._id;
var options = {
$set: {updated_at: new Date()},
$inc: increment
}
yield collection.updateById(id, options);
return this;
};
Cannot pass unique option to collection.index();
Hello,
I have some problems with the query creation and i think the problems are related to the use of $elemMatch
(here src/query.js).
My code is basically like this:
let query = {
"date": {
"$gte": "2015-05-05T00:00:00.000Z", // Not the string, the Date object
"$lte": "2015-05-06T23:59:59.999Z" // Not the string, the Date object
}
};
let result = yield* query.find( query );
But if i enable the DEBUG
i see the generated query is:
monk:queries posts find {"date":{"$elemMatch":{"$gte":"2015-05-05T00:00:00.000Z","$lte":"2015-05-06T23:59:59.999Z"}}}
And i get no results while using the mongo console my query works.
The problem is related to the fact that $elemMatch
works on array fields (see here)
The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.
Code you provide at getting started generates error "SyntaxError: Unexpected identifier"
at yield statements.
Your code needs to be wrapped in a "co" generator function before you can execute it.
var co = require('co');
co(function *(){
var posts;
posts = yield Post.find(); // same as .all()
// match documents with title = "Great title"
posts = yield Post.find({ title: 'Great title' });
posts = yield Post.where('title', 'Great title').find();
posts = yield Post.where('title').equals('Great title').find();
}
I got a array of users _ids (in string format) and executing something like this:
var usersSelected = [ '5524f7944e335ad923701ee5', '5524f7944e335ad923701ee6' ];
var _projects = yield Project.where('clientLeader').in(usersSelected).find();
return me an empty array for _projects.
But in my db i got a item with one of those _ids
{
"_id": {
"$oid": "5525040805b5932c323346fa"
},
"clientLeader": {
"$oid": "5524f7944e335ad923701ee5"
},...
}
I also tried to do something like this
if (usersSelected.length > 0) {
usersSelected.forEach(function (clID) {
clID = ObjectID(clID);
});
}
and use the same array in query but result is the same. How can retrieve items made by users in array?
Does Mongorito support all query expression as of MongoDB 3.x native driver ?
e.g. db..aggregate
If yes can we update it to doc ?
When reconnect mongo After Mongorito.close(), and do some save/query, it will throw an err that "connection is closed by Application."
which is casued by Mongorito.close() is async, but not yield friendly.
Here is an example:
co(function(){
Mongorito.connect(url);
//get data from mongo
Mongorito.close(); //<- it's async, but not yield friendly.
}).then(function(doc){
// ---->connection is still open.
Mongorito.connect(url);
// ---->connection is just closed.
//update doc and save to mongo. <- Get an err caused by "Connection is closed"
Mongorito.close();
})
Then how could I do Mongorito.close() with yield? thanks.
//For example
Post.find({},{name:1})
//
Post.find({},{name:1,_id:0})
//results
{ "_id" : ObjectId("551bbfe1ebe85a041dd81c0b"), "name" : "A3" }
{ "_id" : ObjectId("551bc005ebe85a041dd81c0c"), "name" : "A4" }
{ "_id" : ObjectId("551bc01eebe85a041dd81c0d"), "name" : "A4L" }
{ "_id" : ObjectId("551bc025ebe85a041dd81c0e"), "name" : "A6" }
{ "_id" : ObjectId("551bc02cebe85a041dd81c0f"), "name" : "A6L" }
{ "_id" : ObjectId("551bc035ebe85a041dd81c10"), "name" : "Q3" }
.....
// the results Should not include "_id" ,
//I want to get
{ "name" : "A3" }
{ "name" : "A4" }
{ "name" : "A4L" }
{ "name" : "A6" }
{ "name" : "A6L" }
{ "name" : "Q3" }
...
Hello,
if I want to run the following code:
var post = yield Posts.where("_id", "someid").find();
post.title = "New title";
post.save(); // without yield
var otherPost = yield Posts.where("_id", "someotherid").find();
will it work? Since I don't need to wait for the result of post.save()
, may I run it asynchronously?
I'm running the latest version (0.6.13 ) with iojs 1.5.1 using --es_staging --use_strict.
Here is the stack trace:
|TypeError: Cannot read property 'is' of undefined
| at /usr/src/app/node_modules/mongorito/node_modules/is_js/is.js:29:26
| at root (/usr/src/app/node_modules/mongorito/node_modules/is_js/is.js:18:26)
| at Object.<anonymous> (/usr/src/app/node_modules/mongorito/node_modules/is_js/is.js:23:2)
| at Module._compile (module.js:444:26)
| at Object.Module._extensions..js (module.js:462:10)
| at Module.load (module.js:339:32)
| at Function.Module._load (module.js:294:12)
| at Module.require (module.js:349:17)
| at require (module.js:368:17)
| at Object.<anonymous> (/usr/src/app/node_modules/mongorito/build/mongorito.js:22:10)
| at Module._compile (module.js:444:26)
| at Object.Module._extensions..js (module.js:462:10)
| at Module.load (module.js:339:32)
| at Function.Module._load (module.js:294:12)
| at Module.require (module.js:349:17)
| at require (module.js:368:17)
This is not an issue, I just need a little help here.
In the "Getting Started" page, it shows a way to define a Post with "class" keyword:
class Post extends Model {}
Then, how should I set the collection?
I tried something like this:
class Post extends Model {
constructor() {
super();
this.collection = 'posts';
}
but doesn't work. I don't want to use:
var Post = Model.extend({collection: 'posts'});
I wanna use the "class" keyword.
Then how should I set the collection? thanks.
Hi,
thanks for the great work!
I have a question about the documentation, is there is any place with the full API documentation?
I would suggest adding a Mongorito.use(connection, generatorFn)
method. Where connection
can be an established MongoDB client connection/pool, or a mongodb style connection string. and the generator function receives the Mongorito instance to use, where the connect/disconnect happen in the wrapper... the generatorFn essentially called like co@4
and returning a Promise.
Mongorito.use(cnstr, function *(db) {
//do stuff with db
}).then(function (){
//it's all good
}).catch(function(err){
//oh noes!!!
});
This would allow for someone writing a db layer to use Mongorito with co-style interaction in a generator, but have a final return that can be the promise... allowing for thenable chains outside said method. :-)
Return deep copy, instead of reference (in case of objects) when using .get()
to prevent accidental modification of model's attributes.
Do you have tips on implementing Mongoose-style plugins for Mongorito? I would love to port several of our plugins that add methods, statics, and other query helpers in a DRY fashion.
Not able to access. http://mongorito.com/
on start I get this error:
[Error: Module did not self-register.]
js-bson: Failed to load c++ bson extension, using pure JS version
and when I try to yield SomeModel.all();
this error throws:
TypeError: Cannot read property 'find' of undefined
at Query.find (/Users/artem/Projects/elastic/metagen/node_modules/mongorito/lib/query.js:127:37)
at GeneratorFunctionPrototype.next (native)
My model looks like
var Mongorito = require('mongorito');
var Model = Mongorito.Model;
Mongorito.connect('mongodb://localhost:27017/mydb');
var Api = Model.extend({
collection: function () {
return 'apis';
}
});
module.exports = Api;
I'm using Koajs and iojs
I need to store several models in the same collection, and be able to discriminate between objects, based on the specific model that I'm querying. Like so:
var Account = Mongorito.Model.extend({
collection: 'accounts',
configure: function () {
this.before('save', 'validate');
},
validate: function * (next) {
// some basic validations for all models inheriting from Account
yield next;
}
});
var User = Account.extend({
configure: function () {
this.before('save', 'validateEmailExists');
},
validateEmailExists: function * (next) {
// validate that email exists
yield next;
}
});
Validations, like validateEmailExists
on the User
model, should be fired after the Account
validations pass.
And when I call Account.find()
, I will expect to see all models stored in the accounts
collection for a given query, regardless of the model that was instantiated and saved to create this record. However, if I call User.find()
, I should only return records that were created by the User
model.
Mongoose handles this by using a discriminator function, which is mostly undocumented and I think, rough to use. Is there a simple way to handle this use case in Mongorito?
I just tried to assign this.attributes
to a sanitized object (in a pre-save validation function), and get an error:
Cannot read property 'created_at' of undefined
Which, I assume, means I overrode something that I should've left alone. Is there a clean way to handle this at the model level, or should I do sanitization before it hits the model?
line 320..
save: (callback) -> that = @ fields = do @fields notFields = ['constructor', 'save', 'collection', 'create', 'fields', 'update', 'remove', 'models'] keys = [] for field of @ keys.push field if -1 is notFields.indexOf field async.filter keys, (key, nextKey) -> if that["validate#{ key.camelize() }"] that["validate#{ key.camelize() }"] (valid) -> nextKey not valid else nextKey false , (results) -> return callback yes, results if results.length > 0 Cache.delByTag that.collection, -> ##stuff goes bad at this line if fields._id that.update callback, yes else that.create callback, yes
seems to be not working without cache..
DEBUG: TypeError: Cannot call method 'delByTag' of undefined at /home/blogy/node_modules/mongorito/lib/mongorito.js:432:20 at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:245:13 at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:105:25 at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:242:17 at /home/blogy/node_modules/mongorito/lib/mongorito.js:428:16 at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:238:13 at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:97:13 at Array.forEach (native) at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:26:24 at /home/blogy/node_modules/mongorito/node_modules/async/lib/async.js:96:9
commenting out the caching line .. seems to work!
When I clone repo and try install dependences use npm i
I got error:
npm ERR! Darwin 14.3.0
npm ERR! argv "/Users/zhigalov/.nvm/versions/node/v0.12.0/bin/node" "/Users/zhigalov/.nvm/versions/node/v0.12.0/bin/npm" "i"
npm ERR! node v0.12.0
npm ERR! npm v2.5.1
npm ERR! code EPEERINVALID
npm ERR! peerinvalid The package mongodb does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants mongodb@~1.4
npm ERR! Please include the following file with any support request:
npm ERR! /Users/zhigalov/backend/mongorito/npm-debug.log
When I update node version I got error:
npm ERR! Darwin 14.3.0
npm ERR! argv "/Users/zhigalov/.nvm/versions/node/v0.12.6/bin/node" "/Users/zhigalov/.nvm/versions/node/v0.12.6/bin/npm" "i"
npm ERR! node v0.12.6
npm ERR! npm v2.11.2
npm ERR! path /Users/zhigalov/backend/mongorito/node_modules/mocha/node_modules/jade/bin/jade
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! enoent ENOENT, chmod '/Users/zhigalov/backend/mongorito/node_modules/mocha/node_modules/jade/bin/jade'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
I try in node-v0.12.6 and iojs-v2.3.3.
What I doing wrong?
On the assumption that the changed
object of a model would be primary used when asking for undefined
values, the current implementation of the set
method -which assigns the new value to the changed object under the corresponding key- can lead to false negatives.
Suppose we have a User model with a middleware that makes the following check:
if (!this.changed.admin) {
...
}
If the admin
attribute of that model has changed from true
to false
, that check will indicate that the value didn't change, when it actually did.
When you try to connect with the mongo url schema (mongo://staff.mongohq.com:10000]/foo) instead of a host it does not work.
See last paragraph here http://garyrafferty.com/2011/12/06/Using-NodeJS-ExpressJS-and-MongoHQ-on-Heroku.html
var Mongolian = require('mongolian');
var server, db;
if(process.env.MONGOHQ_URL) {
db = new Mongolian(process.env.MONGOHQ_URL);
} else {
server = new Mongolian;
db = server.db('your_db_name');
}
How can i do to remove attribute ?
i create temporary attributes like token to recover password. But after used this attribute i want to remove from my Document.
I see nothing in set method which remove attribute if nothing is passed or null value...
I created my own short id like {_id: "mJTXnQhs", name: "kevin"}, but when trying to .save(), it throw this err:
Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
It's ok if I insert this doc from mongo's shell like this: db.myCollection.insert({_id: "mJTXnQhs", name: "kevin"}).
Then how should I use my own short id for "_id" with mongorito?
Thanks.
btw, mongorito is amazing, it helps a lot.
Does mongorito support upsert operations i.e. calling collection.update with query, update, and options specifying {upsert: true} ?
Looking at the docs and code, I couldn't see a way to do this unless I'm missing something?
What is the best way to set some field to have defaults, to be unique, max...?
"Nothing special, you will just have to use dirtier syntax, but that's ok." - no one writes their js like that haha dont be dumb
First and foremost, thank you for such great work. I really like your project and the idea of hooks is awesome. Please take a minute to review my issues, I tried the guides and there's no example for this situation.
I currently have a collection with a text index. Using the mongo console, I am able to search my documents like so:
db.cities.find({ '$text': { '$search': 'San Francisco' } }
I have tried this using Mongorito:
let cities = yield City.where({'$text': {$search: 'San Francisco'}}).find();
and also the find version of it:
let cities = yield City.find({'$text': {$search: 'San Francisco'}})
This search never returns any results though. I suspect is due to the fact that it is searching in the existing model properties, and $text
is a reserved mongo property. How could I achieve this?
Also, another common operation when dealing with text search is to sort on the $textScore
meta property. For instance:
db.cities.find({ '$text': { '$search': 'San Francisco' } }, {'score': {'$meta': 'textScore'}}) .sort({'score': {'$meta': 'textScore'}})
This code is finding the city with the text San Francisco in the indexed text property, then projecting the textScore
meta property, then sorting using that score. How would you be able to achieve this using Mongorito?
Thank you.
That is all of code
// test.js
var Mongorito = require('mongorito')
console.log(Mongorito)
I got this error when i perform node --harmony test.js
/Users/xiaofeng/working/node/52dachu/node_modules/mongorito/node_modules/monk/node_modules/mongoskin/lib/utils.js:33
var skinClassName = 'Skin' + NativeClass.name;
^
TypeError: Cannot read property 'name' of undefined
at makeSkinClass (/Users/xiaofeng/working/node/52dachu/node_modules/mongorito/node_modules/monk/node_modules/mongoskin/lib/utils.js:33:43)
at Object.<anonymous> (/Users/xiaofeng/working/node/52dachu/node_modules/mongorito/node_modules/monk/node_modules/mongoskin/lib/admin.js:18:37)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object.<anonymous> (/Users/xiaofeng/working/node/52dachu/node_modules/mongorito/node_modules/monk/node_modules/mongoskin/lib/db.js:20:17)
at Module._compile (module.js:460:26)
I'm trying to find by an ObjectId, but it looks like it's getting converted to a string and thus not returning any documents from the DB.
Simple repo:
Mongorito = require 'mongorito'
ObjectId = require('mongolian').ObjectId
Mongorito.connect ['mongo://...@.../...']
class Doc
Doc = Mongorito.bake Doc
Doc.find( _id: '...', (err, doc) -> console.log doc.length ) // returns 0
Doc.find( _id: new ObjectId('...'), (err, doc) -> console.log doc.length ) // returns 0
Doc.find( title: 'foo', (err,doc) -> console.log doc.length ) // returns 1 (success)
I found this one browsing through the guides.
It currently says
class Post extends Model {
configure () {
this.before('create', 'checkIfExists');
}
* checkIfExists: function (next) {
// checking if post with the
// same title exists in database
yield next;
}
}
But it should actually be
class Post extends Model {
configure () {
this.before('create', 'checkIfExists');
}
* checkIfExists (next) {
// checking if post with the
// same title exists in database
yield next;
}
}
Hello,
I have the following code:
yield User.index('email', { unique: true });
var salt = yield bcrypt.genSalt(10);
var user = new User({
email: this.request.body.email,
password: yield bcrypt.hash(this.request.body.password, salt),
salt: salt
});
try {
yield user.save();
} catch (err) {
console.log("ERROR:", e);
this.body = e;
return;
}
I have the two questions:
Is there any better place to place index(), i currently have it in the main js file, when the server starts. And i feel it should be in model, but don't know where to put it.
The second question is about catching errors, as you can see i have try/catch block. But it doesn't seem to catch any errors, it doesn't logs or puts in the body. I want to ask what i am doing wrong?
Thanks.
Hi, I've run the test suite from my local machine and everything looks like it's passing. However, the badge for CirculeCI is showing a failure.
This project looks like it has almost everything I need except for th ability to have sub document models. Or am I missing something?
Add ability to skip some of the middleware.
I need to make a request like { $or: [{ a:1 }, { b:2 }] }
If I use method
MyModel.or([{ a:1 }, { b:2 }]).find()
than I get a request {"[object Object],[object Object]":{}}
because in here key-value pair is required.
If I use
MyModel.find({ $or: { a:1 }, { b:2 }})
then my request transforms to {"$or":{"$elemMatch":[{"a":1},{"b":2}]}
because of.
So the question is, what is a correct way to make a request like { $or: [{ a:1 }, { b:2 }] }
?
Firstly, I am not using co or any other library like that.
function* p() {
Mongorito.connect('ipaddress/blog');
var post = new Post({
title: 'Node.js with --harmony rocks!',
body: 'Long post body',
author: {
name: 'John Doe'
}
});
yield post.save();
}
var x = p();
console.log(x.next());
The above code should have worked IMO because p() will not yield until the document has been saved.
However, post.save() yields immediately with the output { value: {}, done: false }
.
The following code does save the document but yields a function
yield* post.create(); //replaced yield.post.save()
Output:
{ value: [Function], done: false }
I can see that the new document has been saved in the MongoDB.
Can some one please help?
seems mongorito.connect only accepts url arguments, how can I change some options like poolSize, socketOptions,...?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.