AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.

MongoDB Atlas에서 데이터 쓰기 - 함수

이 페이지의 예시에서는 Atlas 클러스터에서 데이터를 삽입, 업데이트 및 삭제하는 함수에서 MongoDB 쿼리 API를 사용하는 방법을 보여 줍니다.

참고

연합 데이터 소스는 쓰기 작업을 지원하지 않습니다.

이 페이지의 예시에서는 온라인 스토어에서 구매할 수 있는 다양한 품목을 모델링한 store.items collection을 사용합니다. 각 항목에는 name, 인벤토리 quantity 및 고객 배열 reviews 이 있습니다.

store.items의 JSON schema

{ "title": "Item", "required": ["_id", "name", "quantity", "reviews"], "properties": { "_id": { "bsonType": "objectId" }, "name": { "bsonType": "string" }, "quantity": { "bsonType": "int" }, "reviews": { "bsonType": "array", "items": { "bsonType": "object", "required": ["username", "comment"], "properties": { "username": { "bsonType": "string" }, "comment": { "bsonType": "string" } } } } }}

함수에서 코드 스니펫을 사용하려면 먼저 MongoDB 컬렉션 핸들을 인스턴스화해야 합니다:

exports = function() { const mongodb = context.services.get("mongodb-atlas"); const itemsCollection = mongodb.db("store").collection("items"); const purchasesCollection = mongodb.db("store").collection("purchases"); // ... paste snippet here ...}

삽입 작업은 하나 이상의 문서를 가져와서 MongoDB 컬렉션에 추가합니다.

작업 결과를 설명하는 문서를 반환합니다.

collection.insertOne() 메서드를 사용하여 단일 문서를 삽입할 수 있습니다.

다음 함수 스니펫은 단일 항목 문서를 items 컬렉션에 삽입합니다.

const newItem = { "name": "Plastic Bricks", "quantity": 10, "category": "toys", "reviews": [{ "username": "legolover", "comment": "These are awesome!" }]}; itemsCollection.insertOne(newItem) .then(result => console.log(`Successfully inserted item with _id: ${result.insertedId}`)) .catch(err => console.error(`Failed to insert item: ${err}`))

collection.insertMany() 메서드를 사용하면 여러 문서를 동시에 삽입할 수 있습니다.

다음 함수 스니펫은 여러 항목 문서를 items 컬렉션에 삽입합니다.

const doc1 = { "name": "basketball", "category": "sports", "quantity": 20, "reviews": [] };const doc2 = { "name": "football", "category": "sports", "quantity": 30, "reviews": [] }; return itemsCollection.insertMany([doc1, doc2]) .then(result => { console.log(`Successfully inserted ${result.insertedIds.length} items!`); return result }) .catch(err => console.error(`Failed to insert documents: ${err}`))

업데이트 작업은 MongoDB 컬렉션 에서 기존 문서를 찾아 데이터를 수정합니다. 표준 MongoDB 쿼리 구문을 사용하여 업데이트 할 문서를 지정하고 연산자를 업데이트 하여 일치하는 문서에 적용 할 변경 사항을 설명합니다.

Atlas Functions는 업데이트 작업을 실행 하는 동안 문서에 예약된 필드_id__baas_transaction 를 일시적으로 추가합니다. 문서 가 성공적으로 업데이트되면 Atlas Functions에서 이 필드 를 제거 합니다.

다른 도구를 사용하여 컬렉션 의 데이터를 수정하려면 변경하기 전에 이 필드 를 설정 해제 해야 합니다.

예를 들어, mongosh shell 을 사용하여 제품 컬렉션의 문서를 업데이트하는 경우 명령은 다음 코드와 유사할 수 있습니다.

db.products.update( { sku: "unknown" }, { $unset: { _id__baas_transaction: "" } })

collection.updateOne() 메서드를 사용하여 단일 문서를 업데이트할 수 있습니다.

다음 함수 스니펫은 items 컬렉션에 있는 단일 문서의 name을 lego에서 blocks로 업데이트하고 20.99의 price를 추가합니다:

const query = { "name": "lego" };const update = { "$set": { "name": "blocks", "price": 20.99, "category": "toys" }};const options = { "upsert": false }; itemsCollection.updateOne(query, update, options) .then(result => { const { matchedCount, modifiedCount } = result; if(matchedCount && modifiedCount) { console.log(`Successfully updated the item.`) } }) .catch(err => console.error(`Failed to update the item: ${err}`))

collection.findOneAndUpdate() 또는 collection.findOneAndReplace()를 사용하여 단일 문서를 업데이트할 수도 있습니다. 두 메서드 모두 하나의 작업으로 업데이트된 문서를 찾고, 수정하고, 반환할 수 있습니다.

collection.updateMany() 메서드를 사용하여 컬렉션에 있는 여러 문서를 업데이트할 수 있습니다.

다음 함수 스니펫은 items 컬렉션 내 모든 문서의 quantity 값에 10을 곱하여 업데이트합니다:

const query = {};const update = { "$mul": { "quantity": 10 } };const options = { "upsert": false } return itemsCollection.updateMany(query, update, options) .then(result => { const { matchedCount, modifiedCount } = result; console.log(`Successfully matched ${matchedCount} and modified ${modifiedCount} items.`) return result }) .catch(err => console.error(`Failed to update items: ${err}`))

업데이트 작업이 컬렉션의 문서와 일치하지 않는 경우 upsert 옵션을 true로 설정하여 업데이트 쿼리와 일치하는 컬렉션에 새 문서 하나를 자동으로 삽입할 수 있습니다.

다음 함수 스니펫은 board game의 name이 있는 items 컬렉션 내 문서의 quantity를 5만큼 증가시켜 업데이트합니다. upsert 옵션이 활성화되어 있으므로 name 값이 "board game"인 문서가 없으면 MongoDB는 name 필드가 "board game"(으)로 설정되고 quantity 값이 5로 설정된 새 문서를 삽입합니다.

const query = { "name": "board games" };const update = { "$inc": { "quantity": 5 } };const options = { "upsert": true }; itemsCollection.updateOne(query, update, options) .then(result => { const { matchedCount, modifiedCount, upsertedId } = result; if(upsertedId) { console.log(`Document not found. Inserted a new document with _id: ${upsertedId}`) } else { console.log(`Successfully increased ${query.name} quantity by ${update.$inc.quantity}`) } }) .catch(err => console.error(`Failed to upsert document: ${err}`))

필드 연산자를 사용하면 문서의 필드와 값을 수정할 수 있습니다.

$set 연산자를 사용하면 문서의 다른 필드에 영향을 주지 않고 단일 필드의 값을 설정할 수 있습니다.

{ "$set": { "<Field Name>": <Value>, ... } }

$rename 연산자를 사용하여 문서에서 단일 필드의 이름을 변경할 수 있습니다.

{ "$rename": { "<Current Field Name>": <New Field Name>, ... } }

$inc 연산자를 사용하여 필드의 현재 값에 지정된 숫자를 추가할 수 있습니다. 숫자는 양수 또는 음수일 수 있습니다.

{ "$inc": { "<Field Name>": <Increment Number>, ... } }

$mul 연산자 를 사용하여 지정된 숫자와 필드 의 현재 값을 곱할 수 있습니다. 숫자는 양수 또는 음수일 수 있습니다.

{ "$mul": { "<Field Name>": <Multiple Number>, ... } }

배열 연산자를 사용하면 배열 내 값으로 작업할 수 있습니다.

$push 연산자 를 사용하여 배열 필드 의 끝에 값을 추가할 수 있습니다.

{ "$push": { "<Array Field Name>": <New Array Element>, ... } }

$pop 연산자를 사용하여 배열 필드의 첫 번째 또는 마지막 요소를 제거할 수 있습니다. 첫 번째 요소를 제거하려면 -1 을 지정하고 마지막 요소를 제거하려면 1 를 지정합니다.

{ "$pop": { "<Array Field Name>": <-1 | 1>, ... } }

해당 값이 아직 배열 에 포함되어 있지 않은 경우 $addToSet 연산자 를 사용하여 배열 필드 에 값을 추가할 수 있습니다. 값이 이미 있는 경우 $addToSet 은 아무 작업도 수행하지 않습니다.

{ "$addToSet": { "<Array Field Name>": <Potentially Unique Value>, ... } }

$pull 연산자 를 사용하여 배열 필드 에서 지정된 조건과 일치하는 값의 모든 인스턴스를 제거 할 수 있습니다.

{ "$pull": { "<Array Field Name>": <Value | Expression>, ... } }

$[] (All Positional Update) 연산자를 사용하여 배열 필드의 모든 요소를 업데이트할 수 있습니다.

예시

학급의 개별 학생을 설명하는 students 컬렉션이 있다고 가정합니다. 각 문서에는 숫자 배열이 포함된 grades 필드가 포함되어 있습니다.

{ "_id" : 1, "grades" : [ 85, 82, 80 ] }{ "_id" : 2, "grades" : [ 88, 90, 92 ] }{ "_id" : 3, "grades" : [ 85, 100, 90 ] }

다음 업데이트 작업은 모든 학생의 grades 배열에 있는 모든 값에 10을 더합니다.

await students.updateMany( {}, { $inc: { "grades.$[]": 10 } },)

업데이트 후 모든 성적 값이 10씩 증가했습니다.

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }{ "_id" : 2, "grades" : [ 98, 100, 102 ] }{ "_id" : 3, "grades" : [ 95, 110, 100 ] }

$[element] (Filtered Positional Update) 연산자를 사용하여 배열 필터를 기반으로 배열 필드의 특정 요소를 업데이트할 수 있습니다.

예시

학급의 개별 학생을 설명하는 students 컬렉션이 있다고 가정합니다. 각 문서에는 숫자 배열이 포함된 grades 필드가 포함되어 있으며, 이 중 일부는 100보다 큽니다.

{ "_id" : 1, "grades" : [ 15, 92, 90 ] }{ "_id" : 2, "grades" : [ 18, 100, 102 ] }{ "_id" : 3, "grades" : [ 15, 110, 100 ] }

다음 업데이트 작업은 100보다 큰 모든 성적 값을 정확히 100으로 설정합니다:

await students.updateMany( { }, { $set: { "grades.$[grade]" : 100 } }, { arrayFilters: [{ "grade": { $gt: 100 } }] })

업데이트 후 100보다 큰 모든 성적 값은 정확히 100으로 설정되며 다른 모든 성적은 영향을 받지 않습니다.

{ "_id" : 1, "grades" : [ 15, 92, 90 ] }{ "_id" : 2, "grades" : [ 18, 100, 100 ] }{ "_id" : 3, "grades" : [ 15, 100, 100 ] }

삭제 작업은 MongoDB 컬렉션에서 기존 문서를 찾아서 제거합니다. 삭제할 문서를 지정하기 위해 표준 MongoDB 쿼리 구문을 사용합니다.

collection.deleteOne() 메서드를 사용하여 컬렉션에서 단일 문서를 삭제할 수 있습니다.

다음 함수 스니펫은 items 컬렉션에서 name 값이 lego인 문서 하나를 삭제합니다:

const query = { "name": "lego" }; itemsCollection.deleteOne(query) .then(result => console.log(`Deleted ${result.deletedCount} item.`)) .catch(err => console.error(`Delete failed with error: ${err}`))

또는 collection.findOneAndDelete()를 사용하여 단일 문서를 업데이트할 수도 있습니다. 이 메서드를 사용하면 하나의 작업으로 삭제된 문서를 찾고, 제거하고, 반환할 수 있습니다.

collection.deleteMany() 메서드를 사용하여 컬렉션에서 여러 항목을 삭제할 수 있습니다.

다음 스니펫은 items 컬렉션 내 reviews가 없는 모든 문서를 삭제합니다.

const query = { "reviews": { "$size": 0 } }; itemsCollection.deleteMany(query) .then(result => console.log(`Deleted ${result.deletedCount} item(s).`)) .catch(err => console.error(`Delete failed with error: ${err}`))

일괄 쓰기는 여러 쓰기 작업을 단일 작업으로 결합합니다. collection.bulkWrite() 메서드를 사용하여 일괄 쓰기 명령을 실행할 수 있습니다.

exports = async function(arg){ const doc1 = { "name": "velvet elvis", "quantity": 20, "reviews": [] }; const doc2 = { "name": "mock turtleneck", "quantity": 30, "reviews": [] }; var collection = context.services.get("mongodb-atlas") .db("store") .collection("purchases"); return await collection.bulkWrite( [{ insertOne: doc1}, { insertOne: doc2}], {ordered:true});};

MongoDB는 여러 문서를 단일 단위로 읽고 쓸 수 있는 다중 문서 트랜잭션을 지원하므로 컬렉션 전체에서 여러 문서를 읽고 쓸 수 있습니다.

트랜잭션을 수행하려면 다음을 따릅니다:

  1. client.startSession()을 사용하여 클라이언트 세션을 가져오고 시작합니다.

  2. session.withTransaction() 를 호출하여 트랜잭션 을 정의합니다. 이 메서드는 비동기 콜백 함수와 선택적으로 트랜잭션 에 대한 사용자 지정 읽기 및 쓰기 (write) 설정 을 정의하는 구성 객체 를 사용합니다.

    session.withTransaction(async () => { // ... Run MongoDB operations in this callback}, { readPreference: "primary", readConcern: { level: "local" }, writeConcern: { w: "majority" },})
  3. 트랜잭션 콜백 함수에서 트랜잭션에 포함하려는 MongoDB 쿼리를 실행합니다. 트랜잭션에 포함되도록 하려면 각 쿼리에 session을 전달해야 합니다.

    await accounts.updateOne( { name: userSubtractPoints }, { $inc: { browniePoints: -1 * pointVolume } }, { session });
  4. 콜백에 오류가 발생하면 session.abortTransaction()을 호출하여 트랜잭션을 중지합니다. 중단된 트랜잭션은 어떤 데이터도 수정하지 않습니다.

    try { // ...} catch (err) { await session.abortTransaction();}
  5. 트랜잭션이 완료되면 session.endSession()을 호출하여 세션을 종료하고 리소스를 확보합니다.

    try { // ...} finally { await session.endSession();}

다음 예시에서는 'henry'와 'michelle'이라는 두 사용자를 생성하고, 트랜잭션을 사용하여 이들 사용자 간에 'browniePoints'를 단일 단위로 이동합니다:

exports = function () { const client = context.services.get("mongodb-atlas"); db = client.db("exampleDatabase"); accounts = db.collection("accounts"); browniePointsTrades = db.collection("browniePointsTrades"); // create user accounts with initial balances accounts.insertOne({ name: "henry", browniePoints: 42 }); accounts.insertOne({ name: "michelle", browniePoints: 144 }); // trade points between user accounts in a transaction tradeBrowniePoints( client, accounts, browniePointsTrades, "michelle", "henry", 5 ); return "Successfully traded brownie points."; }; async function tradeBrowniePoints( client, accounts, browniePointsTrades, userAddPoints, userSubtractPoints, pointVolume ) { // Step 1: Start a Client Session const session = client.startSession(); // Step 2: Optional. Define options to use for the transaction const transactionOptions = { readPreference: "primary", readConcern: { level: "local" }, writeConcern: { w: "majority" }, }; // Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error) // Note: The callback for withTransaction MUST be async and/or return a Promise. try { await session.withTransaction(async () => { // Step 4: Execute the queries you would like to include in one atomic transaction // Important:: You must pass the session to the operations await accounts.updateOne( { name: userSubtractPoints }, { $inc: { browniePoints: -1 * pointVolume } }, { session } ); await accounts.updateOne( { name: userAddPoints }, { $inc: { browniePoints: pointVolume } }, { session } ); await browniePointsTrades.insertOne( { userAddPoints: userAddPoints, userSubtractPoints: userSubtractPoints, pointVolume: pointVolume, }, { session } ); }, transactionOptions); } catch (err) { // Step 5: Handle errors with a transaction abort await session.abortTransaction(); } finally { // Step 6: End the session when you complete the transaction await session.endSession(); } }