อะไรคือความแตกต่างระหว่างบันทึกและแทรกใน Mongo DB?


149

อะไรคือความแตกต่างระหว่างบันทึกและแทรกใน Mongo DB? ทั้งสองดูเหมือนกัน

db.users.save({username:"google",password:"google123"})

db.users.insert({username:"google",password:"google123"})


1
fyi save () เลิกใช้แล้วใน pymongo
Gabriel Fair

คำตอบ:


147

บันทึกการแทรก Vs:

ในตัวอย่างที่คุณระบุพฤติกรรมนั้นเหมือนกัน

save ทำงานแตกต่างกันหากมันถูกส่งผ่านด้วยพารามิเตอร์ "_id"

สำหรับการบันทึกหากเอกสารมีอยู่_idมันจะเพิ่มการสืบค้นคอลเลกชันบน_idฟิลด์ถ้าไม่มันจะแทรก

หากเอกสารไม่มีอยู่ด้วยค่า _id ที่ระบุเมธอด save () จะทำการแทรกด้วยฟิลด์ที่ระบุในเอกสาร

หากเอกสารมีอยู่ด้วยค่า _id ที่ระบุเมธอด save () จะทำการอัพเดตโดยแทนที่ฟิลด์ทั้งหมดในระเบียนที่มีอยู่ด้วยฟิลด์จากเอกสาร


บันทึก vs อัปเดต :

updateแก้ไขเอกสารที่มีอยู่ที่ตรงกับพารามิเตอร์การสืบค้นของคุณ หากไม่มีเอกสารที่ตรงกันดังกล่าวนั่นคือเมื่อupsertมาในภาพ

  • upsert : false : ไม่มีอะไรเกิดขึ้นเมื่อไม่มีเอกสารดังกล่าว
  • upsert : true : เอกสารใหม่ถูกสร้างขึ้นโดยมีเนื้อหาเท่ากับเคียวรีพารามิเตอร์และอัพเดตพารามิเตอร์

save: ไม่อนุญาตให้ใช้พารามิเตอร์การสืบค้นใด ๆ หาก_idมีอยู่และมีเอกสารที่ตรงกันด้วยเหมือนกันเอกสาร_idนั้นจะถูกแทนที่ เมื่อไม่มีการระบุ _id / ไม่มีเอกสารที่ตรงกันจะเป็นการแทรกเอกสารเป็นเอกสารใหม่


8
ทั้งสองมีไวยากรณ์ที่แตกต่างกัน การอัปเดตมีหลายอาร์กิวเมนต์ ({condition}, {update to doc}, upsert, multi) ในขณะที่ save ยอมรับอาร์กิวเมนต์เดียวเท่านั้น (_id เป็นพารามิเตอร์สำหรับอาร์กิวเมนต์ตามเงื่อนไข). อัปเดตสามารถยอมรับเงื่อนไขใด ๆ แต่บันทึกมีข้อ จำกัด ของเงื่อนไขเพียงบน ฟิลด์ _id
ราหุล

1
ตั้งแต่เวอร์ชัน 2.6 การบันทึกมีอาร์กิวเมนต์ที่สองที่นำเอกสารแสดงข้อกังวลการเขียน docs.mongodb.org/manual/reference/method/db.collection.save
huggie

78

ให้เราพิจารณาสองกรณีที่นี่เพื่อบันทึก: -

1) มี _id ในเอกสาร

2) ไม่มี _id ในเอกสาร

                        Save ()
                        /     \
                       /       \

                 Having _id     Not Having _id 

  ->In this case save will do    ->  It will do normal insertion 
    upsert to insert.Now             in this case as insert() do.
    what that means, it means 
    take the document and replace 
    the complete document having same
    _id.

ให้เราพิจารณาสองกรณีที่นี่สำหรับการแทรก: -

1) มี _id ของเอกสารในการรวบรวม

2) ไม่มี _id ของเอกสารในคอลเล็กชัน

                        Insert()
                       /        \
                      /          \

   Doc Having _id in collection    Doc Not Having _id 
  ->  E11000 duplicate key     ->Insert a new doc inside the collection.
      error index:       

10
ไดอะแกรมระดับถัดไป
John Spiteri

2
โหวตขึ้นเวลาที่ใช้ในการวาดและนำเสนอไดอะแกรมอย่างเรียบร้อย
fanbondi

36

save แทรกหรืออัปเดตเอกสาร

insert ไม่เพียงการแทรก

แต่ในกรณีของคุณมันจะทำเช่นเดียวกันเนื่องจากเอกสารที่ให้ไว้ในบันทึกไม่มี_idฟิลด์


13

โดยยกตัวอย่าง

บันทึกแอปเปิ้ล

db.fruit.save({"name":"apple", "color":"red","shape":"round"})
WriteResult({ "nInserted" : 1 })

db.fruit.find();

{
    "_id" : ObjectId("53fa1809132c1f084b005cd0"),
    "color" : "red",
    "shape" : "round",
    "name" : "apple"
}

บันทึกแอปเปิ้ลด้วย _id ของแอปเปิ้ลที่บันทึกไว้ก่อนหน้านี้

db.fruit.save(
{"_id" : ObjectId("53fa1809132c1f084b005cd0"),"name":"apple", 
"color":"real red","shape":"round"})

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

ตอนนี้แอปเปิ้ลที่เราบันทึกไว้มีการปรับปรุงสีจากสีแดงเป็นสีแดงจริง

db.fruit.find();
{
    "_id" : ObjectId("53fa1809132c1f084b005cd0"),
    "color" : "real red",
    "shape" : "round",
    "name" : "apple"
}

บันทึกแอปเปิ้ลด้วย _id

db.fruit.save({"_id" : ObjectId("55551809132c1f084b005cd0"),
"name":"apple", "color":"real red","shape":"round"})

    WriteResult({ "nMatched" : 0, "nUpserted" : 1, 
"nModified" : 0, "_id": 55551809132c1f084b005cd0 })

แอปเปิ้ลถูกแทรกเนื่องจากไม่มีแอปเปิลที่มี Object ID เดียวกันเพื่อทำการอัปเดต

ใส่สีส้ม

db.fruit.insert({"name":"orange", "color":"orange","shape":"round"})
WriteResult({ "nInserted" : 1 })

ใส่สีส้ม

db.fruit.find();
{
    "_id" : ObjectId("53fa1809132c1f084b005cd0"),
    "color" : "real red",
    "shape" : "round",
    "name" : "apple"
}
{
    "_id" : ObjectId("53fa196d132c1f084b005cd7"),
    "color" : "orange",
    "shape" : "round",
    "name" : "orange"
}
{
    "_id" : ObjectId("55551809132c1f084b005cd0"),
    "color" : "real red",
    "shape" : "round",
    "name" : "apple"
}

ดังนั้นบันทึกจะทำหน้าที่เป็นการอัปเดตหากมาพร้อมกับรหัสวัตถุหากรหัสวัตถุนั้นมีอยู่แล้วและฉลาดกว่าก็จะเป็นการแทรก


10

หากคุณพยายามใช้ "insert" กับ ID ที่ใช้ก่อนหน้านี้ในคอลเลกชันเดียวกันคุณจะได้รับข้อผิดพลาดของรหัสซ้ำกัน หากคุณใช้ "บันทึก" ด้วยรหัสที่มีอยู่ในคอลเลกชันเดียวกันมันจะได้รับการปรับปรุง / เขียนทับ

หากคุณต้องการอัพเดทจริงฉันขอแนะนำให้ใช้ "update" การอัปเดตจะไม่เขียนทับในแบบที่บันทึกหากคุณกำลังบันทึกโดยใช้ ID เดียวกับที่มีอยู่แล้วในคอลเลกชัน

ตัวอย่างเช่นคุณมีสองฟิลด์ "x" และ "y" และคุณต้องการเก็บทั้งสองไว้ แต่เปลี่ยนค่าเป็น "x" หากคุณเลือกคำสั่ง "บันทึก" และไม่รวม y ด้วยค่าก่อนหน้าหรือไม่มี y เลยในการบันทึกของคุณ y จะไม่มีค่าเดียวกันหรืออยู่ที่นั่นอีกต่อไป อย่างไรก็ตามหากคุณเลือกที่จะอัปเดตโดยใช้ $ set และมี x รวมอยู่ในคำสั่งอัปเดตของคุณคุณจะไม่ส่งผลกระทบต่อ y



3

พิจารณาเอกสารด้านล่าง

{ "_id" : 1, "domainName" : "test1.com", "hosting" : "hostgator.com" }

ถ้า db มีเอกสารที่มี _id: 1 อยู่แล้ว

การดำเนินการบันทึกจะโยนข้อยกเว้นตามด้านล่าง

E11000 duplicate key error index ...........

และการดำเนินการแทรกจะแทนที่เอกสาร


db.collection.save()วิธีการปรับปรุงเอกสารหากเอกสารที่มี _id เดียวกันมีอยู่แล้วในฐานข้อมูล เมื่อเอกสารที่มี _id เดียวกันมีอยู่แล้วในฐานข้อมูลเมธอดการบันทึกจะแทนที่เอกสารด้วยเอกสารใหม่อย่างสมบูรณ์ จากหนังสือ - การพัฒนา Pro MongoDB
แจ็คว่างเปล่า


1

db.<collection_name>.save(<Document>) เทียบเท่ากับ InsertOrUpdate Query

ในขณะที่db.<collection_name>.insert(<Document>)เทียบเท่ากับการแทรกแบบสอบถาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.