Mongo $ concatArrays即使为null

时间:2017-02-14 11:01:39

标签: mongodb

我有一大堆文档,可能有两个数组或两个数组中的一个。我想在$ project中合并它们。

我目前正在使用$ concatArrays,但正如文档所述,当其中一个数组为null时,它返回null。我可以弄清楚如何在那里添加一个条件语句,它将返回$ concatArrays或者那里的数组。

示例

我有:

{_id: 1, array1: ['a', 'b', 'b'], array2: ['e', 'e']}
{_id: 2, array1: ['a', 'b', 'b']}
{_id: 3, array2: ['e', 'e']}

我想:

{_id: 1, combinedArray: ['a','b', 'b', 'e', 'e']}
{_id: 2, combinedArray: ['a','b', 'b']}
{_id: 3, combinedArray: ['e', 'e']}

我试过了:

 $project: {
   combinedArray: { '$concatArrays': [ '$array1', '$array2' ] }
 }

 //output (unexpected result): 
    {_id: 1, combinedArray: ['a','b', 'b', 'e', 'e']}
    {_id: 2, combinedArray: null}
    {_id: 3, combinedArray: null}

我也尝试过:

 $project: {
      combinedArray: { '$setUnion': [ '$array1', '$array2' ] }
 }
 //output (unexpected result): 
     {_id: 1, combinedArray: ['a','b', 'e']}
     {_id: 2, combinedArray: ['a','b']}
     {_id: 3, combinedArray: ['e']}

3 个答案:

答案 0 :(得分:9)

正如$concatArrays的文档所说

  

如果任何参数解析为null值或引用该字段   缺少,$ concatArrays返回null。

所以我们需要确保我们没有传递引用缺失字段或null的参数。您可以使用$ifNull运算符执行此操作:

  

计算表达式并返回表达式的值(如果是)   expression计算为非null值。如果表达式计算   到null值,包括未定义值或缺失的实例   fields,返回替换表达式的值。

如果字段表达式不会计算为非空值,则返回空数组:

db.collection.aggregate([
    {$project: {
          combinedArray: { '$concatArrays': [ 
              {$ifNull: ['$array1', []]},
              {$ifNull: ['$array2', []]}
           ] }
       }
    }
])

答案 1 :(得分:1)

您可以使用$ifNull运算符轻松实现此目的:

db.arr.aggregate([
   {
      $project:{
         combinedArray:{
            $concatArrays:[
               {
                  $ifNull:[
                     "$array1",
                     []
                  ]
               },
               {
                  $ifNull:[
                     "$array2",
                     []
                  ]
               }
            ]
         }
      }
   }
])

输出:

{ "_id" : 1, "combinedArray" : [ "a", "b", "b", "e", "e" ] }
{ "_id" : 2, "combinedArray" : [ "a", "b", "b" ] }
{ "_id" : 3, "combinedArray" : [ "e", "e" ] }

答案 2 :(得分:1)

我尝试用嵌套的$ cond做这个,用$ ifNull回答更好,但仍然发布我的答案。

db.getCollection('test').aggregate( [{
 $project: {
    combinedArray: { $cond: [ 
        { $and: [ { $isArray: ["$array1"] }, { $isArray: ["$array2"] } ] }, 
        { '$concatArrays': [ '$array1', '$array2' ] }, 
        { $cond: [ 
            { $isArray: ["$array1"] }, 
            "$array1", 
            "$array2" 
            ] } 
         ] }
     }
}] )