Возвращаемое поле столбца в MongoDB - PullRequest
1 голос
/ 24 мая 2019

У меня есть эта таблица, и я хочу отфильтровать некоторые ее поля. Таблица выглядит так:

/* 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"
        }
    ]
}

И что я на самом деле хочу вернуть, это (простой объект с «status», если 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)? Спасибо за ваше время!

EDIT:

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 голосов
/ 24 мая 2019

Вы идете в правильном направлении, используя {$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"
    ]
  }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...