[node.js] MongoDB 원자 적 “findOrCreate”: findOne, 존재하지 않는 경우 삽입하지만 업데이트하지 않음

제목에서 알 수 있듯이 _id로 문서에 대한 찾기 (하나)를 수행하고, 존재하지 않는 경우 생성 한 다음 발견 또는 생성 여부에 관계없이 콜백에 반환합니다.

findAndModify가 읽은 것처럼 존재하는 경우 업데이트하고 싶지 않습니다. 이것과 관련하여 Stackoverflow에 대한 다른 많은 질문을 보았지만 다시 한 번 아무것도 업데이트하고 싶지 않습니다.

나는 (존재하지 않는) 생성함으로써 실제로 모든 사람들이 말하는 업데이트인지 확실하지 않습니다. 모두 너무 혼란 스럽습니다.



답변

MongoDB 2.4부터는 더 이상 원자 findOrCreate유사 작업을 위해 고유 인덱스 (또는 다른 해결 방법)에 의존 할 필요가 없습니다 .

이 덕분에 운영자 는 문서를 삽입 할 경우에만 발생한다 업데이트를 지정할 수 있습니다 2.4 새로운.$setOnInsert

이것은 upsert옵션 과 결합되어 findAndModify원자 findOrCreate와 유사한 작업 을 수행하는 데 사용할 수 있음을 의미합니다 .

db.collection.findAndModify({
  query: { _id: "some potentially existing id" },
  update: {
    $setOnInsert: { foo: "bar" }
  },
  new: true,   // return new doc if one is upserted
  upsert: true // insert the document if it does not exist
})

으로 $setOnInsert만 삽입되는 문서에 영향을 미치는 기존 문서가 발견되면, 어떤 수정이 발생하지 않습니다. 문서가없는 경우 지정된 _id를 가진 문서를 upsert 한 다음 삽입 전용 세트를 수행합니다. 두 경우 모두 문서가 반환됩니다.


답변

드라이버 버전> 2

최신 드라이버 (> 버전 2) 를 사용하면 더 이상 사용되지 않는 findOneAndUpdatefindAndModify사용하게됩니다. 새로운 방법은 3 개 인수를 취하는 filterupdate(새로운 오브젝트에 삽입 할 기본 속성을 포함) 객체, 그리고 options어디가 upsert 작업을 지정해야합니다.

promise 구문을 사용하면 다음과 같습니다.

const result = await collection.findOneAndUpdate(
  { _id: new ObjectId(id) },
  {
    $setOnInsert: { foo: "bar" },
  },
  {
    returnOriginal: false,
    upsert: true,
  }
);

const newOrUpdatedDocument = result.value;


답변

조금 더럽지 만 그냥 삽입 할 수 있습니다.

키에 고유 인덱스가 있는지 확인하십시오 (_id를 사용하면 괜찮습니다. 이미 고유 한 것입니다).

이런 식으로 요소가 이미 존재하는 경우 포착 할 수있는 예외를 반환합니다.

없는 경우 새 문서가 삽입됩니다.

업데이트 됨 : MongoDB 문서 에서이 기술에 대한 자세한 설명


답변

내가 한 일은 다음과 같습니다 (Ruby MongoDB 드라이버).

$db[:tags].update_one({:tag => 'flat'}, {'$set' => {:tag => 'earth' }}, { :upsert => true })}

존재하는 경우 업데이트하고 그렇지 않은 경우 삽입합니다.


답변