sailsjs use mongodb without ORM

拥有回忆 提交于 2019-12-02 12:29:33

First npm i mongodb because you'll need to wrap any ID's with new ObjectID(idStr).

Then you can do this:

const collection = Pet.getDatastore().manager.collection(Pet.tableName);
const res = await collection.find({ name: { $regex: /blue/ } });
const dataWithObjectIds = await res.toArray();
const dataWithIds = JSON.parse(JSON.stringify(rawDataArr).replace(/"_id"/g, '"id"'));

I created a helper function to do all of this for us:

/**
 * Use by chaining as if you were acting on a collection. So can use .find .aggregate etc.
 * Returns json searializable data.
 *
 * @param {class} model A model
 * @param {number} cnt - Number of chains on this, so I know when it reached the end
 */
function nativeMongoQuery(model, cnt) {

  const collection = model.getDatastore().manager.collection(model.tableName);

  let callCnt = 0;

  let req;

  const proxy = new Proxy({}, {
    get: (_, method) => (...args) => {

      if (!req) req = collection[method](...args);
      else req = req[method](...args);

      callCnt++;

      if (callCnt === cnt) {
        return (async function() {
          const rawDataArr = await req.toArray();
          return JSON.parse(JSON.stringify(rawDataArr).replace(/"_id"/g, '"id"'));
        })();
      } else {
        return proxy;
      }
    }
  });

  return proxy;

}

module.exports = nativeMongoQuery;

I don't like the JSON parse and stringify and global replace. But if I don't do the stringify, then mongo _id's are all ObjectIds.

Use it like this:

const { ObjectId } = require('mongodb');

function makeObjectId(id) {
   return new ObjectId(id);
}

const ownerIds = ['5349b4ddd2781d08c09890f4', '5349b4ddd2781d08c09890f5']
const ownerObjectIds = ownerIds.map(makeObjectId);
await nativeMongoQuery(Pet, 2).find({ owner: { $in: ownerObjectIds } }).sort({ dueAt: 1 });

Here is another example:

const mostRecentlyCreatedPets = await nativeMongoQuery(Pet, 1).aggregate([
  { $match: { owner: { $in: ownerObjectIds } } },
  { $sort: { createdAt: -1 } },
  { $limit: 1 }
]);

The cnt argument tells you how many things you have chained off of there.

As you can see in docs MongoClient.connect() doesn't return Promise object. Instead of this use callback function

module.exports = {
  db:function(){
    var connect = MongoClient.connect("mongodb:***********", function (err, database) {
      //...
      }  
    });  
  }
}

btw. Your call DbService.db function in controller will also fail, cuz your service function also doesn't return Promise

Before you go on, read something about Promises and callback functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!