sailsjs 在没有 ORM 的情况下使用 mongodb
sailsjs use mongodb without ORM
我想将 mongodb 与帆一起使用,但不使用任何 ORM。下面是我连接 mongodb.
的服务
服务:
//DbService.js
const MongoClient = require('mongodb').MongoClient;
module.exports = {
db:function(req, res){
var connect=MongoClient.connect("mongodb:***********").then(function (err, database) {
if(err) console.log(err);
else{
database=database.db('*****');
return connect;
}
});
}
}
连接后我在控制器中调用了它,但出现类型错误:无法读取未定义的 属性 'then'。
控制器:
//HomeControlelr.js
module.exports = {
index:function(req, res){
DbService.db().then(function(err,db) {
console.log(db);
})
}
};
如您在 docs 中所见,MongoClient.connect()
没有 return Promise 对象。而不是使用回调函数
module.exports = {
db:function(){
var connect = MongoClient.connect("mongodb:***********", function (err, database) {
//...
}
});
}
}
顺便说一句。您在控制器中调用 DbService.db
函数也会失败,因为您的服务函数也不会 return Promise
在继续之前,阅读一些关于 Promises 和回调函数的内容
首先 npm i mongodb
因为您需要用 new 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 解析和字符串化以及全局替换。但是如果我不做字符串化,那么 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
参数告诉您您从那里链接了多少东西。
我想将 mongodb 与帆一起使用,但不使用任何 ORM。下面是我连接 mongodb.
的服务
服务:
//DbService.js
const MongoClient = require('mongodb').MongoClient;
module.exports = {
db:function(req, res){
var connect=MongoClient.connect("mongodb:***********").then(function (err, database) {
if(err) console.log(err);
else{
database=database.db('*****');
return connect;
}
});
}
}
连接后我在控制器中调用了它,但出现类型错误:无法读取未定义的 属性 'then'。
控制器:
//HomeControlelr.js
module.exports = {
index:function(req, res){
DbService.db().then(function(err,db) {
console.log(db);
})
}
};
如您在 docs 中所见,MongoClient.connect()
没有 return Promise 对象。而不是使用回调函数
module.exports = {
db:function(){
var connect = MongoClient.connect("mongodb:***********", function (err, database) {
//...
}
});
}
}
顺便说一句。您在控制器中调用 DbService.db
函数也会失败,因为您的服务函数也不会 return Promise
在继续之前,阅读一些关于 Promises 和回调函数的内容
首先 npm i mongodb
因为您需要用 new ObjectID(idStr)
.
那么你可以这样做:
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 解析和字符串化以及全局替换。但是如果我不做字符串化,那么 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
参数告诉您您从那里链接了多少东西。