คอลเลกชัน, สิ่งพิมพ์และการสมัครเป็นพื้นที่หากินของดาวตกที่เอกสารจะหารือในรายละเอียดมากขึ้นเพื่อหลีกเลี่ยงบ่อย สับสนซึ่งบางครั้งได้รับการขยายโดยการทำให้เกิดความสับสนคำศัพท์
นี่คือSacha Greif (ผู้ร่วมเขียนDiscoverMeteor ) อธิบายสิ่งพิมพ์และการสมัครสมาชิกในสไลด์เดียว:
เพื่อให้เข้าใจอย่างถูกต้องว่าทำไมคุณต้องโทรfind()
มากกว่าหนึ่งครั้งคุณต้องเข้าใจว่าคอลเล็กชันสิ่งพิมพ์และการสมัครรับข้อมูลทำงานอย่างไรใน Meteor:
คุณกำหนดคอลเลกชันใน MongoDB ยังไม่มี Meteor ที่เกี่ยวข้อง คอลเลกชันเหล่านี้ประกอบด้วยบันทึกฐานข้อมูล (เรียกอีกอย่างว่า "เอกสาร" โดยทั้ง Mongo และ Meteorแต่ "เอกสาร" มีความกว้างมากกว่าบันทึกฐานข้อมูลตัวอย่างเช่นข้อกำหนดการอัปเดตหรือตัวเลือกคิวรีก็เป็นเอกสารเช่นกัน - วัตถุ JavaScript ที่มีfield: value
คู่)
จากนั้นคุณกำหนด คอลเลกชัน บนเซิร์ฟเวอร์ Meteorด้วยไฟล์
MyCollection = new Mongo.Collection('collection-name-in-mongo')
คอลเลกชันเหล่านี้ประกอบด้วย ข้อมูลทั้งหมดจากคอลเล็กชัน MongoDB และคุณสามารถเรียกใช้งานMyCollection.find({...})
ได้ซึ่งจะส่งคืนเคอร์เซอร์ (ชุดของระเบียนพร้อมวิธีการวนซ้ำและส่งคืน)
เคอร์เซอร์นี้คือ (โดยส่วนใหญ่) ใช้เพื่อเผยแพร่ (ส่ง) ชุดของระเบียน (เรียกว่า"ชุดระเบียน" ) คุณสามารถเลือกที่จะเผยแพร่เฉพาะบางฟิลด์จากเรกคอร์ดเหล่านั้น เป็นชุดระเบียน ( ไม่ใช่คอลเลกชัน) ที่ไคลเอนต์สมัครเพื่อ การเผยแพร่ทำได้โดยฟังก์ชั่นการเผยแพร่ซึ่งเรียกทุกครั้งที่ลูกค้าใหม่สมัครสมาชิกและสามารถใช้พารามิเตอร์เพื่อจัดการระเบียนที่จะส่งคืน (เช่นรหัสผู้ใช้เพื่อส่งคืนเฉพาะเอกสารของผู้ใช้รายนั้น)
ในไคลเอนต์คุณมีคอลเลกชันMinimongo บางส่วนสะท้อนบางส่วนของการบันทึกจากเซิร์ฟเวอร์ "บางส่วน" เนื่องจากอาจมีเพียงบางฟิลด์และ "บางระเบียน" เนื่องจากโดยปกติคุณต้องการส่งไปยังไคลเอ็นต์เฉพาะระเบียนที่ต้องการเพื่อเพิ่มความเร็วในการโหลดหน้าเว็บและเฉพาะข้อมูลที่จำเป็นและได้รับอนุญาต เข้าไป.
Minimongo เป็นการนำ Mongo มาใช้ในหน่วยความจำแบบไม่ถาวร ทำหน้าที่เป็นแคชภายในเครื่องที่จัดเก็บเฉพาะส่วนย่อยของฐานข้อมูลที่ไคลเอ็นต์นี้กำลังทำงานอยู่ แบบสอบถามบนไคลเอนต์ (ค้นหา) จะถูกส่งออกจากแคชนี้โดยตรงโดยไม่ต้องพูดคุยกับเซิร์ฟเวอร์
คอลเลกชัน Minimongo เหล่านี้ในตอนแรกว่างเปล่า พวกเขาเต็มไปด้วย
Meteor.subscribe('record-set-name')
โทร. โปรดทราบว่าพารามิเตอร์ในการสมัครไม่ใช่ชื่อคอลเล็กชัน เป็นชื่อของชุดระเบียนที่เซิร์ฟเวอร์ใช้ในการpublish
โทร การsubscribe()
โทรสมัครไคลเอ็นต์กับชุดเรกคอร์ดซึ่งเป็นชุดย่อยของเร็กคอร์ดจากคอลเล็กชันของเซิร์ฟเวอร์ (เช่นบล็อกโพสต์ล่าสุด 100 รายการ) พร้อมฟิลด์ทั้งหมดหรือส่วนย่อยในแต่ละเร็กคอร์ด (เช่นเฉพาะtitle
และdate
) Minimongo รู้ได้อย่างไรว่าคอลเลคชันใดที่จะวางบันทึกขาเข้า ชื่อของคอลเลกชันจะเป็นcollection
ข้อโต้แย้งที่ใช้ในการเผยแพร่ของการจัดการadded
, changed
และremoved
เรียกกลับหรือถ้าเหล่านี้จะหายไป (ซึ่งเป็นกรณีที่ใช้เวลาส่วนใหญ่) ก็จะเป็นชื่อของคอลเลกชัน MongoDB บนเซิร์ฟเวอร์
การแก้ไขบันทึก
นี่คือสิ่งที่ Meteor ทำให้สิ่งต่างๆสะดวกมาก: เมื่อคุณแก้ไขบันทึก (เอกสาร) ในคอลเลกชัน Minimongo บนไคลเอนต์ Meteor จะอัปเดตเทมเพลตทั้งหมดที่ขึ้นอยู่กับมันทันทีและจะส่งการเปลี่ยนแปลงกลับไปยังเซิร์ฟเวอร์ซึ่งจะทำให้ จะจัดเก็บการเปลี่ยนแปลงใน MongoDB และจะส่งไปยังไคลเอนต์ที่เหมาะสมซึ่งสมัครรับชุดบันทึกรวมถึงเอกสารนั้น สิ่งนี้เรียกว่าการชดเชยเวลาแฝงและเป็นหนึ่งในไฟล์หลักการเจ็ดดาวตก
การสมัครสมาชิกหลายรายการ
คุณสามารถมีการสมัครรับข้อมูลจำนวนมากที่ดึงเรกคอร์ดที่แตกต่างกันออกไป แต่ทั้งหมดจะจบลงในคอลเลกชันเดียวกันบนไคลเอนต์หากมาจากคอลเลกชันเดียวกันบนเซิร์ฟเวอร์ตาม _id
แต่พวกเขาทั้งหมดจะจบลงในคอลเลกชันเดียวกันบนไคลเอ็นต์ถ้ามาจากคอลเลกชันเดียวกันบนเซิร์ฟเวอร์ตั้งอยู่บนพื้นฐานของพวกเขา สิ่งนี้ไม่ได้อธิบายอย่างชัดเจน แต่โดยนัยจากเอกสาร Meteor:
เมื่อคุณสมัครสมาชิกชุดระเบียนจะบอกให้เซิร์ฟเวอร์ส่งระเบียนไปยังไคลเอนต์ ร้านค้าลูกค้าระเบียนเหล่านี้ในคอลเลกชัน Minimongo ท้องถิ่นที่มีชื่อเดียวกับcollection
ข้อโต้แย้งที่ใช้ในการเผยแพร่ของการจัดการadded
, changed
และremoved
เรียกกลับ Meteor จะจัดคิวแอตทริบิวต์ที่เข้ามาจนกว่าคุณจะประกาศ Mongo คอลเลกชันบนไคลเอนต์ด้วยชื่อคอลเลคชันที่ตรงกัน
สิ่งที่ไม่สามารถอธิบายได้คือสิ่งที่เกิดขึ้นเมื่อคุณไม่ได้อย่างชัดเจนใช้added
, สหภาพของทั้งสองชุดของเขตข้อมูลchanged
และสหภาพของทั้งสองชุดของเขตข้อมูลremoved
หรือเผยแพร่ขนย้ายวัสดุที่ทั้งหมด - ซึ่งเป็นส่วนใหญ่ของเวลา ในกรณีที่พบบ่อยที่สุดอาร์กิวเมนต์คอลเลกชันคือ (ไม่น่าแปลกใจ) ที่นำมาจากชื่อของคอลเล็กชัน MongoDB ที่คุณประกาศบนเซิร์ฟเวอร์ในขั้นตอนที่ 1 แต่สิ่งนี้หมายความว่าคุณสามารถมีสิ่งพิมพ์และการสมัครสมาชิกที่แตกต่างกันโดยมีชื่อต่างกันและทั้งหมด ระเบียนจะจบลงในคอลเล็กชันเดียวกันบนไคลเอนต์ ลงไปที่ระดับของฟิลด์ระดับบนสุด Meteor ดูแลที่จะดำเนินการรวมชุดระหว่างเอกสารเพื่อให้การสมัครสมาชิกสามารถทับซ้อนกัน - เผยแพร่ฟังก์ชันที่จัดส่งฟิลด์ระดับบนสุดที่แตกต่างกันไปยังงานไคลเอ็นต์เคียงข้างกันและบนไคลเอนต์เอกสารใน คอลเลกชันจะเป็นไฟล์
ตัวอย่าง: การสมัครสมาชิกหลายรายการที่เติมคอลเลกชันเดียวกันบนไคลเอนต์
คุณมีคอลเล็กชัน BlogPosts ซึ่งคุณประกาศในลักษณะเดียวกันทั้งบนเซิร์ฟเวอร์และไคลเอนต์แม้ว่าจะทำสิ่งที่แตกต่างกัน:
BlogPosts = new Mongo.Collection('posts');
ในไคลเอนต์BlogPosts
สามารถรับบันทึกจาก:
การสมัครสมาชิกบล็อก 10 บทความล่าสุด
Meteor.publish('posts-recent', function publishFunction() {
return BlogPosts.find({}, {sort: {date: -1}, limit: 10});
}
Meteor.subscribe('posts-recent');
สมัครสมาชิกโพสต์ของผู้ใช้ปัจจุบัน
Meteor.publish('posts-current-user', function publishFunction() {
return BlogPosts.find({author: this.userId}, {sort: {date: -1}, limit: 10});
}
Meteor.publish('posts-by-user', function publishFunction(who) {
return BlogPosts.find({authorId: who._id}, {sort: {date: -1}, limit: 10});
}
Meteor.subscribe('posts-current-user');
Meteor.subscribe('posts-by-user', someUser);
สมัครสมาชิกโพสต์ยอดนิยม
- เป็นต้น
เอกสารทั้งหมดนี้มาจากposts
คอลเลกชันใน MongoDB ผ่านBlogPosts
คอลเลกชันบนเซิร์ฟเวอร์และจบลงในBlogPosts
คอลเล็กชันบนไคลเอนต์
ตอนนี้เราเข้าใจแล้วว่าทำไมคุณต้องโทรfind()
มากกว่าหนึ่งครั้ง - ครั้งที่สองที่อยู่บนไคลเอนต์เนื่องจากเอกสารจากการสมัครสมาชิกทั้งหมดจะรวมอยู่ในคอลเลคชันเดียวกันและคุณต้องดึงเฉพาะคนที่คุณสนใจเท่านั้น ตัวอย่างเช่นหากต้องการรับโพสต์ล่าสุดบนไคลเอนต์คุณเพียงแค่สะท้อนข้อความค้นหาจากเซิร์ฟเวอร์:
var recentPosts = BlogPosts.find({}, {sort: {date: -1}, limit: 10});
สิ่งนี้จะส่งคืนเคอร์เซอร์ไปยังเอกสาร / บันทึกทั้งหมดที่ลูกค้าได้รับจนถึงตอนนี้ทั้งโพสต์บนสุดและโพสต์ของผู้ใช้ ( ขอบคุณจอฟฟรีย์ )
BlogPosts.find({})
กับลูกค้าหลังจากสมัครรับข้อมูลสิ่งพิมพ์ทั้งสองฉบับนั่นคือจะส่งคืนเคอร์เซอร์ของเอกสาร / บันทึกทั้งหมดที่อยู่บนไคลเอนต์ทั้งโพสต์บนสุดและโพสต์ของผู้ใช้ ฉันเคยเห็นคำถามอื่น ๆ เกี่ยวกับ SO ซึ่งผู้ถามสับสนกับเรื่องนี้