计算数组中的元素数

I am creating an application, and it has a function which removes elements from an array inside a document in a MongoDB collection.

I need a way to unset the array's field as soon as the array becomes empty right after a remove operation. I need to do this so that I can differentiate between a document that has a non-empty array, and a document that has an empty array.

For example, right now my section collection looks like:

db.section.find({})

{ "_id" : ObjectId("57a0a38ad1c6ef24376477c5"), "sectionid" : "BTE4B", 
 "sectionname" : "BTech 4B", "year" : 4,
 "session" : 2016, "courseid" : "BTE-CS", "password" : "pm8xTE0-",
 "students" : 35, "addedon" : "2016-08-02 19:13:38", "teachers" : [ ] }

 { "_id" : ObjectId("57a0a96bd1c6ef24376477cd"), "sectionid" : "BTE4D",
 "sectionname" : "BTech 4D", "year" : 4, "session" : 2016, "courseid" :
 "BTE-CS", "password" : "sHhKr0Ov", "students" : 41, "addedon" :
 "2016-08-02 19:38:43", "teachers" : [ { "facultyid" : "CS-102",
 "subjectid" : "CS-ALGO" } ] }

I had applied a $pull operation using mgo on the teachers array of the first document, but I need a way to $unset it when it becomes empty.

Currently, I have managed to create a workaround in Go, but I would like to get away without any workarounds.

I hope I am not missing something very trivial here.

Thanks!

Would suggest using the findAndModify() API to do the $pull update operation first, this will return the modified document which you can then access the teachers array for checking. Once you check for array emptiness, you can then issue another update operation that calls the $unset operator on the teachers field if the array key has zero elements.

A canonical example in mongo shell follows:

change = db.section.findAndModify({
    query: { "sectionid": "BTE4D", "teachers.facultyid": "CS-102" },
    update: { "$pull": { "teachers": { "facultyid" : "CS-102" } } },
    new: true
});

printjson(change);

if (!change.teachers[0]) {
     db.section.update(
        { "_id": change._id },
        { "$unset": { "teachers": "" } }
    );
}

db.section.find({ "_id": change._id })

Implementing this with mgo, you would need the Query.Apply method which essentially wraps the findAndModify MongoDB command

change := mgo.Change{
        Update: bson.M{"$pull": bson.M{"teachers": bson.M{"facultyid": "CS-102"}}},
        ReturnNew: true,
}
info, err = col.Find(M{"sectionid": "BTE4D"}).Apply(change, &doc)
fmt.Println(doc.N)

To differentiate empty arrays from non-empty you can use the find command with the $size operator.

If you choose to remove empty arrays you can issue $pull operator with MongoDB findAndModify (refer the mgo documentation for more details) which can atomically return modified document, check if the array is empty and unset it with another query.