Node.js 在旧版本的MongoDB中是否有$expr的替代方案?
在React.js应用程序的Node.js后端中,我使用Node.js 在旧版本的MongoDB中是否有$expr的替代方案?,node.js,mongodb,mongoose,aggregation-framework,Node.js,Mongodb,Mongoose,Aggregation Framework,在React.js应用程序的Node.js后端中,我使用 "mongodb" (as db.version returns): "3.4.10", "mongoose": "5.3.4" 问题是我不能在mongoDB版本{ 返回ObjectID(level); }):null; 让subjectsIn=req.body.subjects&&req.body.subjects.length!==0?req.body.subjects.map(subject=>{ 返回ObjectID(主题);
"mongodb" (as db.version returns): "3.4.10",
"mongoose": "5.3.4"
问题是我不能在mongoDB版本<3.6的情况下使用$expr。
仅仅因为这个问题(不推荐使用的方法等等),升级mongoDB版本似乎花费了很多精力。
所以我想知道是否有一种方法可以不使用$expr就完成我想做的事情
代码如下:
match.$expr = {
$lt: ["$distance", "$range"] // "calculated_distance < tutor_range"
}
匹配。$expr={
$lt:[“$distance”、“$range”]/“计算的距离<导师的范围”
}
你知道怎么做吗?这里是完整的方法,如果你想要更多的细节
exports.search = (req, res) => {
let lat1 = req.body.lat;
let lon1 = req.body.lng;
let page = req.body.page || 1;
let perPage = req.body.perPage || 10;
let radius = req.body.radius || 10000;
let levelsIn = req.body.levels && req.body.levels.length !== 0 ? req.body.levels.map(level => {
return ObjectID(level);
}) : null;
let subjectsIn = req.body.subjects && req.body.subjects.length !== 0 ? req.body.subjects.map(subject => {
return ObjectID(subject);
}) : null;
var options = { page: page, limit: perPage, sortBy: { updatedDate: -1 } }
const isAdmin = req.user ? req.user.role === "admin" || req.user.role === "super-admin" : false;
let match = {}
if (levelsIn) match.levels = { $in: levelsIn };
if (subjectsIn) match.subjects = { $in: subjectsIn }
if (typeof req.body.activated !== "undefined") match.profileActivated = req.body.activated;
if (req.body.from) match.createdAt = { $gte: new Date(req.body.from) };
if (req.body.to) {
if (match.createdAt) match.createdAt.$lte = new Date(req.body.to);
else match.createdAt = { $lte: new Date(req.body.to) };
}
var aggregate = null;
if (!isAdmin) {
match.activated = true
match.profileActivated = true
match.profileOnline = true
}
if (lat1 && lon1) {
match.$expr = {
$lt: ["$distance", "$range"] // "calculated_distance < tutor_range"
}
aggregate = Tutor.aggregate([
{
"$geoNear": {
"near": {
"type": "Point",
"coordinates": [lon1, lat1]
},
"distanceField": "distance", // this calculated distance will be compared in next section
"distanceMultiplier": 0.001,
"spherical": true
}
},
{
$match: match
}
]);
} else {
aggregate = Tutor.aggregate([
{
$match: match
}
]);
}
Tutor
.aggregatePaginate(aggregate, options, function (err, result, pageCount, count) {
if (err) {
return res.status(400).send(err);
}
else {
var opts = [
{ path: 'levels', select: 'name' },
{ path: 'subjects', select: 'name' },
{ path: 'assos', select: 'name' }
];
Tutor
.populate(result, opts)
.then(result2 => {
return res.send({
page: page,
perPage: perPage,
pageCount: pageCount,
documentCount: count,
tutors: result2
});
})
.catch(err => {
return res.status(400).send(err);
});
}
})
};
exports.search=(请求、回复)=>{
设lat1=req.body.lat;
设lon1=req.body.lng;
设page=req.body.page | | 1;
设perPage=req.body.perPage | | 10;
设半径=所需主体半径| | 10000;
让levelsIn=req.body.levels&&req.body.levels.length!==0?req.body.levels.map(level=>{
返回ObjectID(level);
}):null;
让subjectsIn=req.body.subjects&&req.body.subjects.length!==0?req.body.subjects.map(subject=>{
返回ObjectID(主题);
}):null;
var options={page:page,limit:perPage,sortBy:{updateDate:-1}}
const isAdmin=req.user?req.user.role==“admin”| | req.user.role==“super admin”:false;
让match={}
if(levelsIn)match.levels={$in:levelsIn};
if(subjectsIn)match.subjects={$in:subjectsIn}
如果(typeof req.body.activated!=“undefined”)匹配,profileActivated=req.body.activated;
if(req.body.from)match.createdAt={$gte:newdate(req.body.from)};
如果(请求正文至){
if(match.createdAt)match.createdAt.$lte=新日期(请求正文至);
else match.createdAt={$lte:新日期(req.body.to)};
}
var aggregate=null;
如果(!isAdmin){
match.activated=true
match.profileActivated=true
match.profileOnline=true
}
如果(lat1和lon1){
匹配。$expr={
$lt:[“$distance”、“$range”]/“计算的距离<导师的范围”
}
聚合=Tutor.aggregate([
{
“$geoNear”:{
“近”:{
“类型”:“点”,
“坐标”:[lon1,lat1]
},
“distanceField”:“distance”,//下一节将比较此计算的距离
“距离乘数”:0.001,
“球形”:正确
}
},
{
$match:match
}
]);
}否则{
聚合=Tutor.aggregate([
{
$match:match
}
]);
}
家教
.aggregatePaginate(聚合、选项、函数(错误、结果、页面计数、计数){
如果(错误){
返回res.status(400)。发送(err);
}
否则{
变量选项=[
{路径:'levels',选择:'name'},
{路径:'subjects',选择:'name'},
{路径:'assos',选择:'name'}
];
家教
.填充(结果、选项)
。然后(结果2=>{
返回res.send({
第页:第页,
佩奇:佩奇,
pageCount:pageCount,
文档计数:计数,
导师:结果2
});
})
.catch(错误=>{
返回res.status(400)。发送(err);
});
}
})
};
非常感谢您的回答和帮助 您可以使用
$addFields
+$match
而不是$expr
差不多
{"$addFields":{"islt":{"$cond":[{"$lt": ["$distance", "$range"]}, true, false]}}},
{"$match":{"islt":true}}
如果愿意,可以使用额外的项目阶段删除islt变量
{"$project":{"islt":0}}
您可以使用
$addFields
+$match
而不是$expr
差不多
{"$addFields":{"islt":{"$cond":[{"$lt": ["$distance", "$range"]}, true, false]}}},
{"$match":{"islt":true}}
如果愿意,可以使用额外的项目阶段删除islt变量
{"$project":{"islt":0}}
谢谢这个有效:)谢谢!!这是有效的:)