我有一个看起来像这样的集合:
{
"value" : "20",
"type" : "square",
"name" : "form1"
}
{
"value" : "24",
"type" : "circle",
"name" : "form2"
}
{
"value" : "12",
"type" : "square",
"name" : "form3"
}
我想用
name = form2
提取文档,所以我输入:
db.myCollec.find({"name":"form2"} , {"name":1, "type":1, "_id":0})
结果是:
{ "name" : "form2", "type" : "circle" }
现在,如果我想查找带有
name = form4
的文档,我输入:
db.myCollec.find({"name":"form4"} , {"name":1, "type":1, "_id":0})
但是这不会返回任何内容,因为没有具有该名称的文档。
但是我希望返回值看起来像这样:
{ "name" : "form4", "type" : null }
我该怎么做?
您可以使用以下聚合
$match
的数据,Mongodb 不会生成结果。
$facet
聚合,它可以在单个阶段内处理多个聚合管道。
$facet
获取 $match
ed 文档,如果没有找到 ($project
) 数据,则使用 $ifNull
离子。
let searchTerm = "form2"
db.myCollec.aggregate([
{ "$facet": {
"data": [
{ "$match": { "name": searchTerm }},
{ "$project": { "name": 1, "type": 1, "_id": 0 }}
]
}},
{ "$project": {
"name": {
"$ifNull": [{ "$arrayElemAt": ["$data.name", 0] }, searchTerm ]
},
"type": {
"$ifNull": [{ "$arrayElemAt": ["$data.type", 0] }, null]
}
}}
])
Facet 可能是唯一的方法。但到目前为止(MongoDB 7.0)facet 不支持索引。使用facet会导致全集合扫描,从而降低查询效率。
如果
$facet
只有一条管道,则可以将 $match
步骤移出其中,这样可以以更好的性能完成同样的事情。
let searchTerm = "form2"
db.myCollec.aggregate([
{ "$match": { "name": searchTerm }},
{ "$limit": 1 },
{ "$facet": {
"data": [
{ "$project": { "name": 1, "type": 1, "_id": 0 }}
]
}},
{ "$project": {
"name": {
"$ifNull": [{ "$arrayElemAt": ["$data.name", 0] }, searchTerm ]
},
"type": {
"$ifNull": [{ "$arrayElemAt": ["$data.type", 0] }, null]
}
}}
])
为什么如果 result==null 则不检查回调并创建自己的空对象?
let name = "form4";
db.myCollec.find({"name":name} , {"name":1, "type":1, "_id":0}, function(err, result){
if(err) {
// Error handling
return;
}
if (result==null){
result = {"name":name, "type":null};
}
});