如果没有找到结果则返回null默认值

问题描述 投票:0回答:3

我有一个看起来像这样的集合:

{  
"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 }

我该怎么做?

mongodb mongodb-query aggregation-framework
3个回答
8
投票

您可以使用以下聚合

如果查询中没有找到

$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]
    }
  }}
])

0
投票

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]
    }
  }}
])

-1
投票

为什么如果 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};
    }
});
© www.soinside.com 2019 - 2024. All rights reserved.