Предположим, у меня есть следующая коллекция:

{  
  "_id":ObjectId("562e7c594c12942f08fe4192"),
  "first":[  
    {  
      "shape":"square",
      "color":"blue"
    },
    {  
      "shape":"circle",
      "color":"red"
    }
  ],
  "second": []
}

Я хочу сначала найти определенный объект в массиве first и переместить его в поле second

db.collection.findOneAndUpdate({_id: ObjectId("562e7c594c12942f08fe4192")}, {$pull: {first: {color: "red"}}, $push: {// that specific object to second array}})
1
jones 22 Окт 2018 в 14:21

2 ответа

Лучший ответ

Это невозможно сделать за одну операцию. Вы можете сделать это вместо этого:

MyModel.findOne({ _id: ObjectId("562e7c594c12942f08fe4192"), "first.color": "red" }, 'first.$', function (err, doc) {
    MyModel.findByIdAndUpdate(ObjectId("562e7c594c12942f08fe4192"), {
        $pull: { first: { color: "red" } },
        $push: { second: doc.first[0] }
    }, function (err, docs) {  })
});
2
dnickless 22 Окт 2018 в 20:20

Попробуйте это с помощью курсоров.

db.getCollection('test')
    .find({_id: ObjectId("562e7c594c12942f08fe4192")})
    .forEach(function(doc) {
        doc.second = doc.first.filter(function(x) { return x.color === "blue"});
        doc.first = doc.first.filter(function(x) { return x.color !== "blue" });
        db.getCollection('test').save(doc)
    }
)

Замените «синий» выбранным вами элементом.

Однако это будет работать для вашего примера, но за секунду удалит все предыдущие элементы.

Если вы просто хотите добавить его, это должно сработать.

db.getCollection('test')
    .find({_id: ObjectId("562e7c594c12942f08fe4192")})
    .forEach(function(doc) {
         doc.second = doc.second.concat((doc.first.filter((x) => x.color === "green")));
         doc.first = doc.first.filter(function(x) { return x.color !== "green" });
         db.getCollection('test').save(doc)
      }
)
0
Jack 22 Окт 2018 в 12:10
52928163