首页 > 解决方案 > 从不为空的字段创建数组

问题描述

我正在尝试优化A.X = value OR B.Y.Z = value OR C.H = valueMongodb 中的表单查询。数据库引擎使用 3 个不同的索引来执行这样的查询,然后连接结果。它有点慢,所以我决定将所有内容放在一个数组中并在其上创建一个多键索引。所以我创建了一个索引和这个查询来更新条目并填充它:

{
  '$addFields': { 
    'AllowedEntries': [ '$A.X', '$B.Y.Z', '$C.H' ]
  } 
}

它就像一个魅力,但后来我意识到有些值是空值,我希望空值超出数组。所以我去了这个查询:

{
  '$addFields': { 
    'AllowedEntries': { 
      '$map': { 
        'input': [ '$A.X', '$B.Y.Z', '$C.H' ], 
        'as': 'item', 
        'in': { 
          'columns': { 
            '$filter': { 
              'input': '$$item', 
              'as': 'elt', 
              'cond': { '$ne': [ '$$elt', null ] } 
            } 
          }
        }
      } 
    } 
  } 
}

input to $filter must be an array not binData由于错误,这不起作用。我怎样才能原子地做到这一点?理论上我可以执行这个查询,然后拉出空值,但我真的很想在一次更新中完成。

标签: mongodbmongodb-query

解决方案


我最终得到了以下解决方案,将唯一的非空项目放在一个新字段中。非常感谢@Joe 的帮助

{
  '$addFields': { 
    'AllowedEntries': { 
      '$setUnion': [[], { 
        '$filter': { 
          'input': [  '$A.X', '$B.Y.Z', '$C.H' ], 
          'as': 'elt', 
          'cond': '$$elt' 
        } 
      }] 
    } 
  } 
}

请注意,$setUnion使用空数组而不是$addToSet因为后者适用于列名,而前者适用于在我们的例子中过滤的任何表达式。


推荐阅读