在不使用$ match的情况下获取条件内数组的大小

时间:2019-02-20 14:05:57

标签: mongodb aggregation-framework

我有一个查询,需要在哪里确定阵列中的元素数量(我知道可以先通过spyder-py3先用$project然后再用$size完成) ),但是我需要能够处理满足此条件的数组项,如果不满足此条件,则将其保留。我不想通过$match

排除不符合条件的项目

这是对无法满足我需要的功能的数组中的项目进行计数的标准方法:

$match

我需要将其包装成一个条件,而不是通过匹配排除任何东西

我想要为主题数组实现的“逻辑”是这样的:

  1. 如果数组的长度> 1 AND
  2. 有一个值为“ []”或“未选择主题”的数组项
  3. 从主题数组中拉出$ [“]或“未选择主题”时
  4. ELSE返回db.collection.aggregate([ { $project: { _id:1, themeArraySize: { $gt: [ {$size: "$themes" }, 1 ] } } }, { $match: { themeArraySize : true }} , ]) 数组

我苦苦挣扎的部分是如何处理真实的逻辑

将其放在句子中

”“如果数组中有一个主题为[[]”,并且这是唯一主题,则不要理会。但是,如果存在“ []”,并且还有其他主题,则删除“ [ ]”)

我已经开始了:

themes

但是我感觉到我想做的事不可能

谢谢

2 个答案:

答案 0 :(得分:1)

您可以使用$addFields替换现有的themes字段,使用$cond定义逻辑,使用$filterthemes数组中删除某些特定项目,请尝试:

db.collection.aggregate([
    {
        $addFields: {
            themes: {
                $cond: [
                    { $eq: [ { $size: "$themes"} , 1 ] },
                    "$themes",
                    {
                        $filter: {
                            input: "$themes",
                            cond: {
                                $and: [
                                    { $ne: [ "$$this", "[]" ] },
                                    { $ne: [ "$$this", "NO THEMES SELECTED" ] }
                                ]
                            }
                        }
                    }
                ]
            }
        }
    }
])

获取以下数据:

db.collection.save({ themes: [ "something" ] })
db.collection.save({ themes: [ "[]" ] })
db.collection.save({ themes: [ "NO THEMES SELECTED" ] })
db.collection.save({ themes: [ "Something else", "NO THEMES SELECTED" ] })
db.collection.save({ themes: [ "Something else (2)", "[]" ] })

返回:

{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a6"), "themes" : [ "something" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a7"), "themes" : [ "[]" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a8"), "themes" : [ "NO THEMES SELECTED" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6a9"), "themes" : [ "Something else" ] }
{ "_id" : ObjectId("5c6d75246fb49f04a0a1f6aa"), "themes" : [ "Something else (2)" ] }

答案 1 :(得分:1)

非常感谢,感谢@mickl。我不得不对他们的回答做些细微的更改,因为我之前收到错误消息“ $ size的参数必须是数组,但类型为:缺少”

为了解决这个问题,我添加了一个项目阶段来计算数组中的项目数,然后添加一个匹配项以确保该数大于0。这意味着我只能将数组传递给@mickl的解决方案< / p>

完整代码:

{
    "$project": {
        "item": 1,
        "themes": 1,
        "conversationid": 1,
        "numberOfItemsInArray": {
            "$cond": {
                "if": {
                    "$isArray": "$themes"
                },
                "then": {
                    "$size": "$themes"
                },
                "else": 0
            }
        }
    }
},
{
    "$match": {
        "numberOfItemsInArray": {
            "$gt": 0
        }
    }
},
{
    "$addFields": {
        "themes": {
            "$cond": [
                {
                    "$eq": [
                        {
                            "$size": "$themes"
                        },
                        1
                    ]
                },
                "$themes",
                {
                    "$filter": {
                        "input": "$themes",
                        "cond": {
                            "$and": [
                                {
                                    "$ne": [
                                        "$$this",
                                        "[]"
                                    ]
                                },
                                {
                                    "$ne": [
                                        "$$this",
                                        "NO THEMES SELECTED"
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    }
},
{
    "$unwind": "$themes"
},