Home > Enterprise >  Remove 3 similar items from an array using mongodb
Remove 3 similar items from an array using mongodb

Time:06-23

I have this document and i need remove only 3 items with name "Test" using only 1 request. { "_id" : 1, "items" : ["Test, "Test", "Test", "Test", "Test", "Sword", "Sword]}

It must become { "_id" : 1, "items" : ["Test", "Test", "Sword", "Sword]} after request.

CodePudding user response:

Maybe something like this:

db.collection.aggregate([
{
  "$unwind": "$items"
},
{
 $group: {
  _id: "$items",
  cnt: {
    $sum: 1
  },
  it: {
    $push: "$items"
  },
  origid: {
    "$first": "$_id"
    }
  }
 },
 {
  $project: {
  _id: "$origid",
  items: {
    $slice: [
      "$it",
      0,
      2
     ]
   }
  }
 },
 {
  $group: {
  _id: "$_id",
  items: {
     $push: "$items"
    }
  }
},
{
$addFields: {
  items: {
    "$reduce": {
      "input": "$items",
      "initialValue": [],
      "in": {
        "$concatArrays": [
          "$$this",
          "$$value"
          ]
        }
      }
    }
   }
  }
])

Explained:

  1. unwind the items array so you can group after
  2. group by item so you get the repeating values
  3. project with slice to remove more then 2x items in array
  4. group to form back the document but without the >2 repeating values
  5. project with concatArrays to concat arrays of items.

Playground

CodePudding user response:

You can use this aggregation to get the desired result. The query uses the $reduce Aggregate Array Operator to iterate over the items array, and discards the first 3 matching "Test" items.

db.collection.aggregate([
{ 
    $set: {
        items: {
            $reduce: { 
                input: "$items", 
                initialValue: { result: [], count: 0 }, 
                in: {
                    $cond: [ { $and: [ { $eq: [ "$$this", "Test" ] }, { $lt: [ "$$value.count", 3 ] } ] },
                        { result: "$$value.result", count: { $add: [ "$$value.count", 1 ] } },
                        { result: { $concatArrays: [ "$$value.result", [ "$$this" ] ] }, count: "$$value.count" }
                    ]
                }
            }
        }
    }
},
{
    $set: {
        items: "$items.result"
    }
}
])
  • Related