Node.js SAILSJ使用不带ORM的mongodb

Node.js SAILSJ使用不带ORM的mongodb,node.js,mongodb,promise,sails.js,q,Node.js,Mongodb,Promise,Sails.js,Q,我想使用mongodb与帆,但没有任何ORM。下面是我连接mongodb的服务。 服务: 连接后,我在控制器中调用了它,但得到了TypeError:无法读取未定义的属性'then' 控制器: //HomeControlelr.js module.exports = { index:function(req, res){ DbService.db().then(function(err,db) {

我想使用mongodb与帆,但没有任何ORM。下面是我连接mongodb的服务。
服务:

连接后,我在控制器中调用了它,但得到了TypeError:无法读取未定义的属性'then'

控制器:

//HomeControlelr.js
    module.exports = {
            index:function(req, res){
                DbService.db().then(function(err,db) {
                    console.log(db);
                })
            }
    };
正如您在
MongoClient.connect()中看到的那样,
不会返回Promise对象。而不是使用回调函数

module.exports = {
  db:function(){
    var connect = MongoClient.connect("mongodb:***********", function (err, database) {
      //...
      }  
    });  
  }
}
顺便说一句,您在控制器中的调用
DbService.db
功能也将失败,因为您的服务功能也不会返回承诺


在继续之前,请先阅读一些关于承诺和回调函数的内容

npm i mongodb,因为您需要用
新ObjectID(idStr)
包装任何ID

然后你可以这样做:

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"'));
我创建了一个助手函数来为我们完成所有这些:

/**
 * 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;
我不喜欢JSON解析、字符串化和全局替换。但是如果我不做stringify,那么mongo-id都是
ObjectId
s

像这样使用它:

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 });
下面是另一个例子:

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

cnt
参数告诉您有多少东西是从那里链接起来的。

为什么要这样做?水线是为什么大多数人会首先使用帆的一个重要原因。我只需要获取数据。我不想为所有集合编写scema。
MongoClient.connect()
似乎没有返回
承诺。作为替代方案,您可以始终使用吃水线要素
const mostRecentlyCreatedPets = await nativeMongoQuery(Pet, 1).aggregate([
  { $match: { owner: { $in: ownerObjectIds } } },
  { $sort: { createdAt: -1 } },
  { $limit: 1 }
]);