MongoDB中列的返回字段

时间:2019-05-24 14:19:34

标签: mongodb mongodb-query

我有这张桌子,我想过滤它的某些字段。该表如下所示:

/* 1 */
{
    "_id" : ObjectId("5ce7db93db1ec10d08941d44"),
    "name" : "john",
    "age" : "22",
    "group" : "A",
    "nodes" : [ 
        {
            "name1" : "some_name1",
            "status" : "completed"
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5ce7e2fd726ed9434c32aaba"),
    "name" : "mike",
    "age" : "23",
    "group" : "B",
    "nodes" : [ 
        {
            "dev_name" : "some_name_dev1",
            "status" : "not completed"
        }, 
        {
            "dev_name" : "some_name_dev2",
            "status" : "completed"
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("5ce7e36c726ed9434c32aabc"),
    "name" : "anne",
    "age" : "24",
    "group" : "C",
    "status" : "pending"
}

/* 4 */
{
    "_id" : ObjectId("5ce7f05e726ed9434c32aabe"),
    "name" : "jane",
    "age" : "27",
    "group" : "D",
    "nodes" : [ 
        {
            "dev_name" : "some_name_dev6",
            "status" : "not completed"
        }, 
        {
            "dev_name" : "some_name_dev7"
        }
    ]
}

我真正想要返回的是这个(如果nodes不存在,则为带有“状态”的简单对象,如果存在nodes,则为一个数组:

/* 1 */
[{
    "status" : "completed"
}]

/* 2 */
[{
    "status" : "not completed"
},
{
     "status" : "completed"
}]

/* 3 */
{
    "status" : "pending"
}

/* 4 */
[{
    "status" : "not completed"
}]

我这样做了:

db.getCollection('user').find( 
    { 
        $or: [
                {
                    "status": { $ne:null } 
                },  
                {
                    "nodes.status":{ $exists: true }
                } 
              ] 
     },  
     { 
         'status': 1, 
         'nodes.status': 1,
         '_id': 0
     } 
)

结果是这样,我有点卡住了:

/* 1 */
{
    "nodes" : [ 
        {
            "status" : "completed"
        }
    ]
}

/* 2 */
{
    "nodes" : [ 
        {
            "status" : "not completed"
        }, 
        {
            "status" : "completed"
        }
    ]
}

/* 3 */
{
    "status" : "pending"
}

/* 4 */
{
    "nodes" : [ 
        {
            "status" : "not completed"
        }, 
        {}
    ]
}

我如何获得想要的东西(摆脱nodes字段)?谢谢您的时间!

编辑:

db.getCollection('user').find( 
    { 
        $or: [
                {
                    "status": { $ne:null } 
                },  
                {
                    "nodes.status":{ $exists: true }
                } 
              ] 
     },  
     { 
         'status': 1, 
         'nodes.status': 1,
         '_id': 0
     },
     [ { "$project": { "status": { "$ifNull" : ["$nodes.status", ""] } } } ]
)

1 个答案:

答案 0 :(得分:0)

使用{$project: <expression>}可以更改退货文件的格式,这是正确的方向。但是我认为$ifNull的使用不正确。根据文档,$ifNull的输入为

{ $ifNull: [ <expression>, <replacement-expression-if-null> ] }

完整查询:

db.getCollection('user').find( 
{ 
    $or: [
            {
                "status": { $ne:null } 
            },  
            {
                "nodes.status":{ $exists: true }
            } 
          ] 
 },  
 { 
     'status': { "$ifNull" : ["$status", "$nodes.status"] },  
     '_id': 0
 })

编辑:使用聚合而不是简单的find(),因为$ ifNull运算符仅在聚合中可用。

db.collection.aggregate([


{
    $match: {  #behaves like the find operator
      $or: [
        {
          "status": {
            $ne: null
          }
        },
        {
          "nodes.status": {
            $exists: true
          }
        }
      ]
    }
  },
  {
    $project: {
      "status": {
        "$ifNull": [
          "$status",
          "$nodes.status"
        ]
      },
      "_id": 0
    }
  }
])

输出:

[
  {
    "status": [
      "completed"
    ]
  },
  {
    "status": [
      "not completed",
      "completed"
    ]
  },
  {
    "status": "pending"
  },
  {
    "status": [
      "not completed"
    ]
  }
]