我正在处理一个带有criteria
对象的查询,该对象将作为该查询的第一个参数传递:
module.exports = (criteria, sortProperty, offset = 0, limit = 20) => {
// write a query that will follow sort, offset, limit options only
// do not worry about criteria yet
console.log(criteria);
const query = Artist.find({ age: { $gte: 19, $lte: 44 } })
.sort({ [sortProperty]: 1 })
.skip(offset)
.limit(limit);
return Promise.all([query, Artist.count]).then(results => {
return {
all: results[0],
count: results[1],
offset: offset,
limit: limit
};
});
};
默认情况下,criteria
对象只有一个name
属性,它是一个空字符串。
age
属性指向同时分配了min
和max
值的对象。我在yearsActive
对象的内部还有一个criteria
属性,并且还具有一个min
和max
值。
所以有三个不同的属性:age
,name
和yearsActive
。
这对我来说是一个极具挑战性的挑战,如果您看的远,那是我所能达到的。
在我的criteria
属性被控制台记录时,它只有一个名称{ name: "" }
。首次启动时,默认情况下没有yearsActive
或age
。这样便是滑块的作用所在。当我开始在前端移动这些滑块时,它会将age
和yearsActive
附加到criteria
对象上。>
因此,我需要弄清楚如何更新查询以考虑例如不同的年龄,并且我一直在考虑在辅助函数内使用if
条件。
答案 0 :(得分:1)
关于我留下的评论。
将数据检索到UI时,您至少具有三种状态。在这种情况下,我建议您使用聚合以将数据作为模型检索为您的业务。
例如,您遇到的问题是,有时您不知道 age 或 yearsActive 的最大值或最小值,但是您也应该可能是 ObjectId 的标识符,该标识符将用于更新由该属性标识的模型。
Artist.aggregate([
{
$match: { age: { $gte: 19, $lte: 44 } }
},
{
$sort: { yourProperty: 1 }
},
{
$skip: 10
},
{
$limit: 10
},
{
$project: {
// You set your properties to retrieve with the 1 as flag
propertieX: 1,
"another.property": 1,
"age.max": {
$cond: {
if: { $eq: [ "", "$age.max" ] },
then: 0, // Or the value that you want to set it
else: "$age.max"
}
}
}
}]);
另一种状态是当您根据从表单提交的参数进行查询时。
如果您保证使用所需的逻辑检索模型。例如,您应该在每个请求中使用 $ project 返回此模型,并在不存在前端操作的情况下应用默认值,因为在搜索中应该易于管理。>
{
ObjectId: YOUR_OBJECT_ID,
age: {
min: YOUR_MIN_VALUE,
max: YOUR_MAX_VALUE
},
yearsActive: {
min: YOUR_MIN_VALUE,
max: YOUR_MAX_VALUE
}
}
最后,当您发送数据进行保存时,应该发送返回的整个模型,但必须要注意的是,通过 ObjectId 仅标识该元素以进行更新。
注意:根据我从您的问题中了解到的信息,我会采用这种方法,如果我对我的解释不好,请告诉我,如果您想要共享更多信息或打开存储库以用代码理解,应该更容易让我理解该问题。
答案 1 :(得分:0)
所以我决定这样做是因为创建所有单独的Artist.find({})
代码看起来很混乱,是创建一个单独的辅助函数:
const buildQuery = (criteria) => {
console.log(criteria);
};
此辅助函数正在与criteria
对象一起调用,我必须以这种方式构成对象,使其以我要搜索Artist
集合的方式表示查询。
这使我难以理解的原因是,结构不完善的对象用于搜索具有随机属性的集合,例如age
,其最小值和最大值是Mongo不知道如何处理的默认情况下。 MongoDB不知道min和max到底是什么意思。
因此,在帮助器函数中,我从此函数中为return
创建了一个单独的对象,该对象将代表我想发送给Mongo的实际query
。
const buildQuery = (criteria) => {
console.log(criteria);
const query = {};
};
我无论如何都没有修改该对象,我只是从该UI对象中读取一些所需的搜索结果或用户希望看到的内容,因此我将该对象命名为query
,并添加了这个想法的age
。
const buildQuery = (criteria) => {
console.log(criteria);
const query = {};
query.age = {};
};
我决定针对想要查找的特定年龄范围在辅助函数中进行if
有条件的操作。
const buildQuery = (criteria) => {
console.log(criteria);
const query = {};
if (criteria.age) {
query.age = {};
}
};
因此,这就是Mongo查询运算符发挥作用的地方。我要考虑的两个运算符是大于或等于($gte
)和小于或等于($lte
)个运算符。
这是我在实践中实际实现的方式:
const buildQuery = (criteria) => {
console.log(criteria);
const query = {};
if (criteria.age) {
query.age = {
$gte: criteria.age.min,
$lte: criteria.age.max
};
}
};
此处的query
对象最终将从buildQuery
函数返回:
const buildQuery = (criteria) => {
console.log(criteria);
const query = {};
if (criteria.age) {
query.age = {
$gte: criteria.age.min,
$lte: criteria.age.max
};
}
return query;
};
该query
对象将传递给查找操作:
module.exports = (criteria, sortProperty, offset = 0, limit = 20) => {
// write a query that will follow sort, offset, limit options only
// do not worry about criteria yet
const query = Artist.find(buildQuery(criteria))
.sort({ [sortProperty]: 1 })
.skip(offset)
.limit(limit);
return Promise.all([query, Artist.count]).then(results => {
return {
all: results[0],
count: results[1],
offset: offset,
limit: limit
};
});
};
const buildQuery = (criteria) => {
console.log(criteria);
const query = {};
if (criteria.age) {
query.age = {
$gte: criteria.age.min,
$lte: criteria.age.max
};
}
return query;
};
所以我在这里要做的就是获得Artist.find({ age: { $gte: minAge, $lte: maxAge })
的等价物。
所以对于yearsActive
,我决定实现几乎相同的东西:
const buildQuery = criteria => {
console.log(criteria);
const query = {};
if (criteria.age) {
query.age = {
$gte: criteria.age.min,
$lte: criteria.age.max
};
}
if (criteria.yearsActive) {
}
return query;
};
因此,如果用户更改了滑块,我将期望我的条件对象具有在其上定义的YearsActive属性,如下所示:
const buildQuery = criteria => {
console.log(criteria);
const query = {};
if (criteria.age) {
query.age = {
$gte: criteria.age.min,
$lte: criteria.age.max
};
}
if (criteria.yearsActive) {
query.yearsActive = {
$gte: criteria.yearsActive.min,
$lte: criteria.yearsActive.max
}
}
return query;
};