source

mongoose를 통해 아이템을 mongo 어레이에 푸시합니다.

itover 2023. 3. 18. 08:31
반응형

mongoose를 통해 아이템을 mongo 어레이에 푸시합니다.

기본적으로 '사람들'이라는 이름의 mongodb 컬렉션을 가지고 있는데 스키마는 다음과 같습니다.

people: {
         name: String, 
         friends: [{firstName: String, lastName: String}]
        }

데이터베이스와 연결하여 빈 친구 배열로 '사람'을 만드는 매우 기본적인 express 어플리케이션이 있습니다.

어플리케이션의 세컨더리 장소에는 친구를 추가하기 위한 양식이 있습니다.이 폼은 적절한 피플 오브젝트를 참조하기 위해 이름 필드와 함께 firstName 및 lastName을 입력한 후 POST를 입력합니다.

저는 새 친구 개체를 만들고 친구 배열에 "푸시"하는 데 어려움을 겪고 있습니다.

이 때 mongo 업데이트 을 mongo에서 하는 것을 있습니다.$push검색 기준에 이은 두 번째 주장이지만, mongoose가 이것을 하도록 하는 적절한 방법을 찾을 수 없을 것 같습니다.

db.people.update({name: "John"}, {$push: {friends: {firstName: "Harry", lastName: "Potter"}}});

약,라고가정하면var friend = { firstName: 'Harry', lastName: 'Potter' };

다음 두 가지 옵션이 있습니다.

모델 인메모리 업데이트 후 저장(플레인 javascript array.push):

person.friends.push(friend);
person.save(done);

또는

PersonModel.update(
    { _id: person._id }, 
    { $push: { friends: friend } },
    done
);

mongoose가 제공하는 이점(훅, 검증 등)을 더 존중하기 때문에 가능하면 항상 첫 번째 옵션을 선택하려고 합니다.

그러나 동시 쓰기를 많이 하면 레이스 상황에 직면하게 되고, 결과적으로 매번 모델 전체를 교체하고 이전에 추가한 친구를 잃는 것을 막을 수 있는 심각한 버전 오류가 발생합니다.그러니 꼭 필요할 때만 후자로 가세요.

$push 연산자는 지정된 값을 배열에 추가합니다.

{ $push: { <field1>: <value1>, ... } }

$syslog는 값을 요소로 하여 배열 필드를 추가합니다.

위의 답변은 모든 요건을 충족합니다만, 저는 다음과 같이 작업을 했습니다.

var objFriends = { fname:"fname",lname:"lname",surname:"surname" };
People.findOneAndUpdate(
   { _id: req.body.id }, 
   { $push: { friends: objFriends  } },
  function (error, success) {
        if (error) {
            console.log(error);
        } else {
            console.log(success);
        }
    });
)

Mongoose를 사용하여 항목을 배열에 푸시하는 또 다른 방법은 $addToSet입니다. 하나의 항목만 배열에 푸시하는 경우입니다.$push 연산자는 객체가 이미 존재하는지 여부에 관계없이 어레이에 객체를 추가할 뿐입니다.$addToSet은 중복되지 않도록 객체가 어레이에 존재하지 않는 경우에만 객체를 추가합니다.

PersonModel.update(
  { _id: person._id }, 
  { $addToSet: { friends: friend } }
);

배열에 추가할 개체를 검색합니다.발견되면 아무것도 하지 않습니다.그렇지 않으면 배열에 추가합니다.

참고 자료:

$push문서를 업데이트하고 배열에 새 값을 삽입합니다.

검색:

db.getCollection('noti').find({})

검색 결과:

{
    "_id" : ObjectId("5bc061f05a4c0511a9252e88"),
    "count" : 1.0,
    "color" : "green",
    "icon" : "circle",
    "graph" : [ 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 2.0
        }
    ],
    "name" : "online visitor",
    "read" : false,
    "date" : ISODate("2018-10-12T08:57:20.853Z"),
    "__v" : 0.0
}

업데이트:

db.getCollection('noti').findOneAndUpdate(
   { _id: ObjectId("5bc061f05a4c0511a9252e88") }, 
   { $push: { 
             graph: {
               "date" : ISODate("2018-10-24T08:55:13.331Z"),
               "count" : 3.0
               }  
           } 
   })

업데이트 결과:

{
    "_id" : ObjectId("5bc061f05a4c0511a9252e88"),
    "count" : 1.0,
    "color" : "green",
    "icon" : "circle",
    "graph" : [ 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 2.0
        }, 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 3.0
        }
    ],
    "name" : "online visitor",
    "read" : false,
    "date" : ISODate("2018-10-12T08:57:20.853Z"),
    "__v" : 0.0
}

처음에 나는 이 코드를 시도했다.

const peopleSchema = new mongoose.Schema({
  name: String,
  friends: [
    {
      firstName: String,
      lastName: String,
    },
  ],
});
const People = mongoose.model("person", peopleSchema);
const first = new Note({
  name: "Yash Salvi",
  notes: [
    {
      firstName: "Johnny",
      lastName: "Johnson",
    },
  ],
});
first.save();
const friendNew = {
  firstName: "Alice",
  lastName: "Parker",
};
People.findOneAndUpdate(
  { name: "Yash Salvi" },
  { $push: { friends: friendNew } },
  function (error, success) {
    if (error) {
      console.log(error);
    } else {
      console.log(success);
    }
  }
);

단, 첫 번째 친구(Johny Johnson 등)만 저장되고 기존 "친구" 배열의 어레이 요소를 푸시하는 목표는 데이터베이스에서 "첫 번째 친구"만 표시되고 "친구" 배열은 하나의 요소만 표시되므로 아래에 간단한 솔루션이 기재되어 있습니다.

const peopleSchema = new mongoose.Schema({
  name: String,
  friends: [
    {
      firstName: String,
      lastName: String,
    },
  ],
});
const People = mongoose.model("person", peopleSchema);
const first = new Note({
  name: "Yash Salvi",
  notes: [
    {
      firstName: "Johnny",
      lastName: "Johnson",
    },
  ],
});
first.save();
const friendNew = {
  firstName: "Alice",
  lastName: "Parker",
};
People.findOneAndUpdate(
  { name: "Yash Salvi" },
  { $push: { friends: friendNew } },
  { upsert: true }
);

"{ upsert: true }"를 추가하면 문제가 해결되어 코드가 저장되고 실행되면 "friends" 어레이에 2개의 요소가 있음을 알 수 있습니다.upsert = true 옵션은 개체가 없는 경우 개체를 생성합니다. 기본값은 false로 설정됩니다.

동작하지 않는 경우는, 이하의 스니펫을 사용해 주세요.

People.findOneAndUpdate(
  { name: "Yash Salvi" },
  { $push: { friends: friendNew } },
).exec();

이를 위한 간단한 방법은 다음을 사용하는 것입니다.

var John = people.findOne({name: "John"});
John.friends.push({firstName: "Harry", lastName: "Potter"});
John.save();

저 같은 경우에는 이렇게 했어요.

  const eventId = event.id;
  User.findByIdAndUpdate(id, { $push: { createdEvents: eventId } }).exec();

중첩된 필드로 푸시 - 점 표기 사용

예를 들어 스키마가 있을 때 중첩된 필드로 푸시하는 방법을 알고 싶은 사용자를 위해 사용합니다.

const UserModel = new mongoose.schema({
  friends: {
    bestFriends: [{ firstName: String, lastName: String }],
    otherFriends: [{ firstName: String, lastName: String }]
  }
});

점 표기법을 사용하면 다음과 같습니다.

const updatedUser = await UserModel.update({_id: args._id}, {
  $push: {
    "friends.bestFriends": {firstName: "Ima", lastName: "Weiner"}
  }
});

항목을 푸시할 수 있는 방법 - 공식 문서

const schema = Schema({ nums: [Number] });
const Model = mongoose.model('Test', schema);

const doc = await Model.create({ nums: [3, 4] });
doc.nums.push(5); // Add 5 to the end of the array
await doc.save();

// You can also pass an object with `$each` as the
// first parameter to use MongoDB's `$position`
doc.nums.push({
  $each: [1, 2],
  $position: 0
});
doc.nums;

// 이것이 이 질문에 대한 저의 해결책입니다.

// worKingHours (개체 배열)에 새 개체를 추가합니다. -- >

workingHours: [
  {
    workingDate: Date,
    entryTime: Date,
    exitTime: Date,
  },
],

// employeeRoutes.js

const express = require("express");
const router = express.Router();
const EmployeeController = require("../controllers/employeeController");



router
  .route("/:id")
  .put(EmployeeController.updateWorkingDay)

//employeeModel.js

const mongoose = require("mongoose");
const validator = require("validator");

const employeeSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, "Please enter your name"],
    },
    address: {
      type: String,
      required: [true, "Please enter your name"],
    },
    email: {
      type: String,
      unique: true,
      lowercase: true,
      required: [true, "Please enter your name"],
      validate: [validator.isEmail, "Please provide a valid email"],
    },
    phone: {
      type: String,
      required: [true, "Please enter your name"],
    },
    joiningDate: {
      type: Date,
      required: [true, "Please Enter your joining date"],
    },
    workingHours: [
      {
        workingDate: Date,
        entryTime: Date,
        exitTime: Date,
      },
    ],
  },
  {
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  }
);

const Employee = mongoose.model("Employee", employeeSchema);

module.exports = Employee;

//employeeController.js

///////////////////////////////////////////// 아래에 솔루션이 있습니다.

// 다른 요일 추가, 입장 및 퇴장 시간 추가

exports.updateWorkingDay = async (req, res) => {
  const doc = await Employee.findByIdAndUpdate(req.params.id, {
    $push: {
      workingHours: req.body,
    },
  });
  res.status(200).json({
    status: "true",
    data: { doc },
  });
};

https://www.youtube.com/watch?v=gtUPPO8Re98

저도 이 문제에 부딪혔어요.내 수정사항은 하위 스키마를 만드는 것이었다.사용하시는 모델의 예에 대해서는, 아래를 참조해 주세요.

----인물 모델

const mongoose = require('mongoose');
const SingleFriend = require('./SingleFriend');
const Schema   = mongoose.Schema;

const productSchema = new Schema({
  friends    : [SingleFriend.schema]
});

module.exports = mongoose.model('Person', personSchema);

***중요: SingleFriend.schema -> 스키마에는 반드시 소문자를 사용합니다.

--- 자 스키마

const mongoose = require('mongoose');
const Schema   = mongoose.Schema;

const SingleFriendSchema = new Schema({
  Name: String
});

module.exports = mongoose.model('SingleFriend', SingleFriendSchema);

언급URL : https://stackoverflow.com/questions/33049707/push-items-into-mongo-array-via-mongoose

반응형