我在编写查找/汇总mongo查询时遇到问题,我的要求是获取所有文档,但条件如下:
假设我有2个文档:
{
_id: 5ccaa76939d95d395791efd2,
name: 'John Doe',
email: 'john.doe@foobar.com',
private: true
}
{
_id: 5ccaa76939d95d395791efd2,
name: 'Jane Doe',
email: 'jane.doe@foobar.com',
private: false
}
现在我要查询的查询是字段private
是否为真,那么当我查询时,如果private
为真,我必须获取除电子邮件字段以外的所有文档,例如:
{
_id: 5ccaa76939d95d395791efd2,
name: 'John Doe',
private: true
}
{
_id: 5ccaa76939d95d395791efd2,
name: 'Jane Doe',
email: 'jane.doe@foobar.com',
private: false
}
在aggregate()中尝试了$redact
,$cond
,$$PRUNE
,$$DESCEND
,还遇到了$$REMOVE
(看起来是最新功能),但是无法获得所需的输出。请通过
答案 0 :(得分:4)
您可以使用$$REMOVE
从返回的文档中删除字段。
db.collection.aggregate([
{ "$addFields": {
"email": {
"$cond": [
{ "$eq": ["$private", true] },
"$$REMOVE",
"$email"
]
}
}}
])
答案 1 :(得分:0)
谢谢安东尼·温兹莱特(Anthony Winzlet),他的解决方案就像一个魅力。
如果任何人都遇到同样的问题,并且需要包含多个字段,我可以通过编写以下方法来做到这一点:
function condition(privateFieldLimitationArray, publicFieldLimitationArray) {
const condition = {};
privateFieldLimitationArray.map((d, i) => {
condition[d] = {
"$cond": [
{ "$eq": ["$private", true] },
"$$REMOVE",
publicFieldLimitationArray.includes(d) ? '$$REMOVE' : '$'+d
]
}
});
return condition;
}
然后,您可以使用上述功能,例如:
const privateLimitationArray = ['updatedAt', 'createdAt', 'email', 'lname', 'friendslist', '__v'];
const publicLimitationArray = ['updatedAt', 'createdAt', '__v'];
YourModel.aggregate([
{
$match: {
// Your query to find by
}
}, {
"$addFields": condition(privateLimitationArray, publicLimitationArray)
}
])
.then(result => {
// handle result
})
.catch(error => {
// handle error
});