79

I'm asking this because when I write unit tests, I want to drop the test database and insert some initialize data, and also check the data in mongodb in testing. So I need raw operations to mongodb.

How to do this in mongoose? What I can do now is just create the connection, and not find any document in mongoose's official site.

 var mongoose = require('mongoose');
 mongoose.connect('mongo://localhost/shuzu_test');

 // get the connection
 var conn = mongoose.connection;

But how to:

  1. drop the database
  2. create a collection
  3. write some data to a collection
  4. query a collection
  5. drop a collection
Freewind
  • 193,756
  • 157
  • 432
  • 708

6 Answers6

84

You can run mongodb commands using the native NodeJS driver by using mongoose.connection.db. This accesses the NodeJS MongoDB driver, and you don't need to create a mongoose model.

An insert

mongoose.connection.db.collection('userCollection').insert({
  username: 'captain1',
  firstName: 'Steve',
  lastName: 'Rogers', 
});

An update

mongoose.connection.db.collection('userCollection').update(
  {someFilterProperty: true},
  {$set: {
     siteId: new mongoose.mongo.ObjectId('56cb91bdc5946f14678934ba'),
     hasNewSiteId: true}},
  {multi: true});
});

You can send every command specific to that database using the database connection db reference mongoose.connection.db.

This is the mongoose API doc: http://mongoosejs.com/docs/api.html#connection_Connection-db

Important: Note some of the options in the NodeJS driver are different than the options in MongoDB shell commands. For example findOneAndUpdate() uses returnOriginal instead of returnNewDocument. See here and here for more on this.

steampowered
  • 11,809
  • 12
  • 78
  • 98
  • 1
    I think this is the best general-access way to the native driver. For those searching in the original Mongoose API docs, here is the link for `Connection.prototype.db`: http://mongoosejs.com/docs/api.html#connection_Connection-db – edmundo096 Mar 16 '17 at 17:11
  • 1
    How do you print the result of the query? – CodyBugstein Jan 29 '18 at 16:36
  • 1
    I know this is old, but just for people that are still finding this, you can do this to get results: `Mongoose.connection.db.collection('collectionname').find({}).toArray((err,results) => { console.log(results); });` – Matt Fiocca Jan 10 '20 at 15:34
53

See the section on "Driver Access" in the docs: http://mongoosejs.com/

Basically you can get access to the node-mongodb-native driver by doing YourModel.collection and then you can insert or remove or drop or whatever you need.

There's not a doc, but with this approach you'll get access to everything in here: https://mongoosejs.com/docs/api.html#collection-js

Edit:

In your case you may want to skip using mongoose in your test suite and use the node-mongodb-native directly, or even write a simple mongodb shell script that can be run before your tests start.

Tal
  • 1,091
  • 12
  • 25
Jamund Ferguson
  • 16,721
  • 3
  • 42
  • 50
  • 1
    About "using mognodb-native directly", I found if I defined indexes in mongoose schemas, they won't work well if I use mongodb-native to insert some data directly. – Freewind May 25 '12 at 07:41
  • That's interesting. I thought the ensureIndex was run on startup? Hmm. Ahh yes, but this is in your test suite so it's not doing the Mongoose calls at all. – Jamund Ferguson May 25 '12 at 13:10
  • I have a complex MongoDB script that runs from the command line as follows: $ mongo mydb task.js Since I can't run shell scripts in my server environment and need to schedule the above task, I figured I could run the Mongo script from a Node script. Is this possible through the native driver? – Sam Oct 26 '12 at 03:18
  • Does your environment allow you to setup cron jobs at all? – Jamund Ferguson Oct 26 '12 at 15:54
  • 3
    This answer refers to documentation which isn't very clear. Why not just write the code *and* link to the specific page in the documentation. – basickarl Jun 01 '16 at 15:58
  • 6
    I don't see "Driver Access" on that page anymore. – rtf Aug 18 '16 at 18:50
6

use this to run raw operations in mongoose.

  Model_name.collection.insertMany(array, { ordered: false },function(err, success){
            console.log(success);
        });
jitendra rajput
  • 612
  • 10
  • 15
  • 8
    This answer requires a model to exist. The question asks how to use "raw mongodb", which implies the user may not want the added requirement of a model. – steampowered Mar 19 '17 at 12:59
4

Have encountered same trouble, to cleanup DBs after tests, and actual answer only confused because of absence "code blocks", so dig docs/code once more, for others-time-saving purpose posting this ;)

Mongoose collection extends Mongodb collection

/* * section collection.js * http://mongoosejs.com/docs/api.html#collection-js */

interface CollectionBase extends mongodb.Collection {

Documentation : http://mongodb.github.io/node-mongodb-native/2.1/api/Collection.html

Same goes for the connection:

The Connection class exposed by require('mongoose') is actually the driver's NativeConnection class. connection.js defines a base class that the native versions extend. See: http://mongoosejs.com/docs/api.html#drivers-node-mongodb-native-connection-js

So all "RAW" operations can be performed on collection/connection, assuming that you have

 var connection = mongoose.connection;

then:

1.drop the database:

connection.dropDatabase()

2.create a collection

connection.collection('newcollection') // creates if not exists

3.write some data to a collection

connection.collection('mybenotnewcollection').bulkWrite([
  { insertOne: { whatewer: { you: 'need' } } },
]);

4.query a collection

that's obviously not a question: findAll, find, aggregate, all allowed (see the Docs)

5.drop a collection

connection.collection('notsonewcollection').drop()
2oppin
  • 1,941
  • 20
  • 33
  • Works all fine. But how can I check whether a collection exists? If I'm unsing connection.listCollections(), I'm getting an error: listCollections is not a function – mcAngular2 Dec 28 '18 at 09:50
  • @mcAngular2 check docs https://mongoosejs.com/docs/api.html#connection_Connection-collections connection.collections – 2oppin Dec 28 '18 at 10:09
3
const mongoose = require('mongoose');
mongoose.connect(uri, options);
var db = mongoose.connection;
db.once('open', function () {
  db.collection('collection').find().toArray(function(err, result){
        console.log(result);
  });
}
hardyRocks
  • 307
  • 3
  • 10
1

The mongoose object has a mongo prototype which gives you access to native mongo driver

mongoose.mongo
Curious Flower
  • 347
  • 3
  • 7