So basically I have this data
{
company: {
subscriptions: [
{
"name": "test1",
"updatedAt": ISODate("2021-10-19T06:40:33.583Z")
},
{
"name": "test2",
"updatedAt": ISODate("2021-10-19T06:40:33.583Z")
},
{
"services": {
"1": {
"createdAt": ISODate("2021-10-19T06:40:33.583Z"),
"updatedAt": ISODate("2021-10-19T06:40:33.583Z")
}
},
"updatedAt": ISODate("2021-10-19T06:40:33.583Z")
}
]
}
}
Currently I don't know how this data is inserted on the collection.
The weird data is this one.
{
"services": {
"1": {
"createdAt": ISODate("2021-10-19T06:40:33.583Z"),
"updatedAt": ISODate("2021-10-19T06:40:33.583Z")
}
},
"updatedAt": ISODate("2021-10-19T06:40:33.583Z")
}
How can I use mongodb $pull to remove this inside subscriptions array?
CodePudding user response:
Base on @Takis_ answer I found a solution. Here is what I did
const cursor = await Company.find({
$and: [
{
"subscriptions": { $exists: true, $ne: [] }
}
]
}).cursor();
await cursor.eachAsync(async company => {
let isUpdate = false;
const found = find(company.subscriptions, subscription => subscription.name === undefined);
if (!found) return
try {
const res = await Company.updateOne(
{
"_id": mongoose.Types.ObjectId(company._id),
},
{
$pull: { subscriptions: { name: { $exists: false } } }
}
);
} catch(err) {
log(`ERROR removing subscription entry for company ${company.name} - ${company._id}`);
}
})
CodePudding user response:
Query1
- $pull, if member doesnt have a field called name, it gets removed
db.collection.updateMany({},
{
$pull: {
"company.subscriptions": {
name: {
"$exists": false
}
}
}
})
Query2
- alternative way with pipeline
- this removes a member of the array, if doesnt have a field
name
(or name is false/null) - services that you dont want to remove doesnt have a name so it will be filtered out
pipeline update requires MongoDB >= 4.2
db.collection.updateMany({},
[
{
"$set": {
"company.subscriptions": {
"$filter": {
"input": "$company.subscriptions",
"cond": "$$this.name"
}
}
}
}
])
If your updateMany method doesnt accept pipeline you can run it like as command
db.runCommand(
{
update: "yourCollection",
updates: [
{
q: { },
u: [
{
"$set": {
"company.subscriptions": {
"$filter": {
"input": "$company.subscriptions",
"cond": "$$this.name"
}
}}}
],
multi: true
}
],
ordered: false
}
)