Search code examples
mongodbmongodb-querynosqlaggregation-frameworkaggregation

PlanExecutor error during aggregation :: caused by :: $arrayToObject requires an object keys of 'k' and 'v'. Found incorrect number of keys:1


I have created an aggregation query on mongo playground as also shown with the following data:

    [
        {
         postId: "1",
         comment: {
            text_sentiment: "positive",
            topic: "A"
         }
        },

        {
         postId: "2",
         comment: {
            text_sentiment: "negative",
            topic: "A"
         }
        },
        {
         postId: "3",
         comment: {
          text_sentiment: "positive",
          topic: "B"
         }
       },

    {
     postId: "4",
     comment: {
        topic: "B"
     }
    }
  ]

In the data above postId = 4 does not have text_sentiment key inside but every other doc has.

Query:

db.collection.aggregate([
    {
        $match: {
        //    surveyId: "e6d38e1ecd",
        "comment.topic": {
            $exists: 1
        },
        
        }
    },
    {
        $group: {
        _id: {
            topic: "$comment.topic",
            text_sentiment: "$comment.text_sentiment"
        },
        total: {
            $sum: 1
        },
        postIds: {
            $push: "$postId"
        }
        }
    },
    {
        $group: {
        _id: "$_id.topic",
        total: {
            $sum: "$total"
        },
        text_sentiments: {
            $push: {
            k: "$_id.text_sentiment",
            v: "$total"
            }
        },
        postIds: {
            "$push": "$postIds"
        }
        }
    },
    {
        $project: {
        topic: "$_id",
        topicOccurance: "$total",
        sentiment: {
            "$arrayToObject": "$text_sentiments"
        },
        postIds: {
            $setUnion: [
            {
                $reduce: {
                input: "$postIds",
                initialValue: [],
                in: {
                    $concatArrays: [
                    "$$value",
                    "$$this"
                    ]
                }
                }
            }
            ]
        }
        }
    },
    {
        $sort: {
        "topicOccurance": -1
        }
    }
    ])

Running this gives query failed: (Location40392) PlanExecutor error during aggregation :: caused by :: $arrayToObject requires an object keys of 'k' and 'v'. Found incorrect number of keys:1.

How can I know if each comment has both topics and comment before this aggregation could be run?


Solution

  • You can use the $ifNull operator to provide a default value and then post-process your results after aggregation is done:

    {
        $group: {
            _id: {                
                topic: "$comment.topic",
                text_sentiment: {
                    "$ifNull": [
                        "$comment.text_sentiment",
                        "unknown"
                    ]
                }
            },
            total: {
                $sum: 1
            },
            postIds: {
                $push: "$postId"
            }
        }
    }
    

    Mongo Playground

    EDIT:alternatively, you can use $all to check whether text_sentiments array contains both values:

    {
        $match: {
            "text_sentiments.k": {
                $all: [
                    "positive",
                    "negative"
                ]
            }
        }
    }
    

    Mongo Playground