20200210084301_remove-duplicate-deleted-things.mjs 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /* eslint-disable no-unused-vars */
  2. const tags = ['server-ce', 'server-pro', 'saas']
  3. async function removeDuplicates(collection, field) {
  4. const duplicates = await collection.aggregate(
  5. [
  6. {
  7. $group: {
  8. _id: { projectId: `$deleterData.${field}` },
  9. dups: { $addToSet: '$_id' },
  10. count: { $sum: 1 },
  11. },
  12. },
  13. { $match: { count: { $gt: 1 } } },
  14. ],
  15. { allowDiskUse: true }
  16. )
  17. let duplicate
  18. while ((duplicate = await duplicates.next())) {
  19. // find duplicate items, ignore the most recent and delete the rest
  20. const items = await collection
  21. .find(
  22. { _id: { $in: duplicate.dups } },
  23. { projection: { _id: 1 }, sort: { 'deleterData.deletedAt': -1 } }
  24. )
  25. .toArray()
  26. items.pop()
  27. const ids = items.map(item => item._id)
  28. await collection.deleteMany({ _id: { $in: ids } })
  29. }
  30. }
  31. const migrate = async client => {
  32. const { db } = client
  33. await removeDuplicates(db.deletedProjects, 'deletedProjectId')
  34. await removeDuplicates(db.deletedUsers, 'deletedUserId')
  35. }
  36. const rollback = async client => {
  37. // can't really do anything here
  38. }
  39. export default {
  40. tags,
  41. migrate,
  42. rollback,
  43. }