繁体   English   中英

合并和删除嵌套数组中的元素

[英]merge and remove elements in nested arrays

我有这个数组,我想合并嵌套数组中对象内的所有元素并删除重复项..该数组是 mongo db populate 的输出,所以从那里得到的答案或只是 js 会很棒:)

 "visitors": [
        [
            {
                "name": "matan",
                "id": "61793e6a0e08cdcaf213c0b1"
            },
            {
                "name": "shani",
                "id": "61793e910e08cdcaf213c0b5"
            }
        ],
        [
            {
                "name": "david",
                "id": "6179869cb4944c6b19b05a23"
            },
            {
                "name": "orit",
                "id": "617986e535fdf4942ef659bd"
            }
        ],
        [
            {
                "name": "david",
                "id": "6179869cb4944c6b19b05a23"
            },
            {
                "name": "orit",
                "id": "617986e535fdf4942ef659bd"
            }
        ]
    ]

想要这个输出 -

"visitors": [
        {
            "name": "matan",
            "id": "61793e6a0e08cdcaf213c0b1"
        },
        {
            "name": "shani",
            "id": "61793e910e08cdcaf213c0b5"
        },
        {
            "name": "david",
            "id": "6179869cb4944c6b19b05a23"
        },
        {
            "name": "orit",
            "id": "617986e535fdf4942ef659bd"
        },
]

这些是我的收藏,我需要让所有访客都在一个太阳系上,所以 > 太阳能 > 行星 > 访客

const solarsModel = new Schema({
    planets: [ { type: Schema.Types.ObjectId ,ref:'planet'} ],
    starName: { type: String, required: true, default: "" }
})

const planetModel = new Schema({
    planetName: { type: String, required: true, default: "" },
    system:{type: Schema.Types.ObjectId, ref: 'solar'},
    visitors: [{ type: Schema.Types.ObjectId , ref: 'visitor'}]
})

const visitorModel = new Schema({
    visitorName:{ type: String, required: true, default: "" },
    homePlanet: {type: Schema.Types.ObjectId, ref:"planet" },
    visitedPlanets: [{ type: Schema.Types.ObjectId, ref:"planet" }]
})

这就是我为实现结果所做的工作,我很想使用 Aggregate ..

  const response = await solarModel
    .findById({ _id: data.id })
    .select({ starName: 1, _id: 0 })
    .populate({
      path: "planets",
      select: { visitors: 1, _id: 0 },
      populate: {
        path: "visitors",
        select: "visitorName",
      },
    })
    .exec();

(1)展平数组数组

visitors = visitors.flat();

这给了我们这个:

[
  { name: 'matan', id: '61793e6a0e08cdcaf213c0b1' },
  { name: 'shani', id: '61793e910e08cdcaf213c0b5' },
  { name: 'david', id: '6179869cb4944c6b19b05a23' },
  { name: 'orit', id: '617986e535fdf4942ef659bd' },
  { name: 'david', id: '6179869cb4944c6b19b05a23' },
  { name: 'orit', id: '617986e535fdf4942ef659bd' }
]

(2) 获取唯一id

let uniqueIds= [...new Set(visitors.map(v => v.id)]

这给了我们这个:

[
   '61793e6a0e08cdcaf213c0b1',
   '61793e910e08cdcaf213c0b5',
   '6179869cb4944c6b19b05a23',
   '617986e535fdf4942ef659bd'
]

(3) 仅根据 uniqueIds 获取新的访问者列表

visitors = uniqueIds.map(id => {
   let name = visitors.find(v => v.id === id).name;

   return {
      id,
      name
   }
});

这给了我们这个:

[
  { name: 'matan', id: '61793e6a0e08cdcaf213c0b1' },
  { name: 'shani', id: '61793e910e08cdcaf213c0b5' },
  { name: 'david', id: '6179869cb4944c6b19b05a23' },
  { name: 'orit', id: '617986e535fdf4942ef659bd' },
]

您可以像这样使用aggregate()

  • 由于嵌套数组, $unwind两次
  • $group使用$addToSet来避免重复。
db.collection.aggregate([
  {
    "$unwind": "$visitors"
  },
  {
    "$unwind": "$visitors"
  },
  {
    "$group": {
      "_id": null,
      "visitors": {
        "$addToSet": {
          "id": "$visitors.id",
          "name": "$visitors.name"
        }
      }
    }
  }
])

示例在这里

询问

  • 用 concat 减少以展平
  • union 与一个空数组,只是为了删除重复项
  • 如果您有除访客以外的其他字段,则它们不受影响

*在您的驱动程序上试一试,操场有现场订单问题,有时会丢失,在这里我们比较文档以删除重复项。

aggregate(
[{"$set": 
   {"visitors": 
     {"$setUnion": 
       [{"$reduce": 
         {"input": "$visitors",
          "initialValue": [],
          "in": {"$concatArrays": ["$$value", "$$this"]}}},
        []]}}}])

结果

[{
  "visitors": [
    {
      "name": "david",
      "id": "6179869cb4944c6b19b05a23"
    },
    {
      "name": "matan",
      "id": "61793e6a0e08cdcaf213c0b1"
    },
    {
      "name": "orit",
      "id": "617986e535fdf4942ef659bd"
    },
    {
      "name": "shani",
      "id": "61793e910e08cdcaf213c0b5"
    }
  ]
}]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM