สองคอลเลกชัน mongodb ในหนึ่งแบบสอบถาม

ฉันมีลูกค้ากลุ่มใหญ่และกลุ่มข้อมูลลูกค้ากลุ่มใหญ่ กลุ่มต่างๆ จะถูกแยกออกจากกัน และฉันไม่ต้องการรวมไว้ในกลุ่มเดียว (เนื่องจากเซิร์ฟเล็ตอื่นๆ ที่ทำงานอยู่แล้ว) แต่ตอนนี้ฉันต้อง "เข้าร่วม" ข้อมูลจากทั้งสองคอลเลกชันในผลลัพธ์เดียว

เนื่องจากแบบสอบถามควรส่งคืนผลลัพธ์จำนวนมาก ฉันไม่ต้องการสืบค้นเซิร์ฟเวอร์เพียงครั้งเดียวแล้วใช้ผลลัพธ์เพื่อสืบค้นอีกครั้ง ฉันยังกังวลเกี่ยวกับการรับส่งข้อมูลระหว่างเซิร์ฟเวอร์กับ DB และหน่วยความจำที่ชุดผลลัพธ์จะครอบครองใน RAM ของเซิร์ฟเวอร์

วิธีการทำงานตอนนี้คือฉันได้รับรายชื่อลูกค้าที่เกี่ยวข้องจากคอลเลกชัน 'ลูกค้า' และส่งรายการนี้ไปยังแบบสอบถามของคอลเลกชัน 'ข้อมูลลูกค้า' จากนั้นฉันจึงได้รับผลลัพธ์แบบรวมเท่านั้น

ฉันต้องการตัดการรับและส่งรายชื่อลูกค้าจากและกลับไปยังเซิร์ฟเวอร์ ให้เซิร์ฟเวอร์ถามตัวเอง ให้แบบสอบถามของการรวบรวมข้อมูลลูกค้าถามการรวบรวมลูกค้าสำหรับรายชื่อลูกค้าที่เกี่ยวข้อง

ฉันจะใช้ขั้นตอนการจัดเก็บ (ฟังก์ชันจาวาสคริปต์) เพื่อทำแบบสอบถามในฐานข้อมูลและส่งคืนเฉพาะไคลเอนต์ที่เกี่ยวข้องออกจากคอลเลกชันได้อย่างไร มีวิธีเขียนแบบสอบถามที่รวมผลลัพธ์จากคอลเลกชันอื่นหรือไม่


person Toda Raba    schedule 15.02.2015    source แหล่งที่มา
comment
ไม่มีตัวเลือกดังกล่าวในการสืบค้นหลายคอลเลกชันใน monogb สิ่งหนึ่งที่ใช้ ReferenceField หรือ ForienKey   -  person itzMEonTV    schedule 15.02.2015


คำตอบ (4)


"ข่าวดีสำหรับทุกคน" แบบสอบถามแบบรวมนี้ทำงานได้ดีใน mongo shell เป็นแบบสอบถามแบบรวม

db.clientData.aggregate([{
    $match: {
        id: {
            $in: db.clients.distinct("_id",
            {
                "tag": "qa"
            })
        }
    }
},
    $group: {
        _id: "$computerId",
        total_usage: {
            $sum: "$workingTime"
        }
    }
}]);
person Toda Raba    schedule 23.02.2015

แนวคิดหลักในการสร้างแบบจำลองข้อมูล MongoDB คือ เขียนหนัก ไม่ใช่อ่านหนัก: จัดเก็บข้อมูลในรูปแบบที่คุณต้องการสำหรับการอ่าน ไม่ใช่ในรูปแบบบางรูปแบบที่ย่อให้เหลือน้อยที่สุด/หลีกเลี่ยงความซ้ำซ้อน (เช่น การใช้ โมเดลข้อมูลที่ไม่ปกติ)

ฉันไม่ต้องการรวมเป็นคอลเลกชันเดียว

นั่นไม่ใช่ข้อโต้แย้งที่ดี

ฉันยังกังวลเกี่ยวกับการรับส่งข้อมูลระหว่างเซิร์ฟเวอร์และฐานข้อมูล [...]

หากคุณต้องการข้อมูล คุณต้องมีข้อมูล วิธีการสอบถามสร้างความแตกต่างที่นี่อย่างไร

[...] และหน่วยความจำที่ชุดผลลัพธ์จะครอบครองใน RAM ของเซิร์ฟเวอร์

ปริมาณข้อมูลมีขนาดใหญ่มากจนคุณต้องการ สตรีม จากเซิร์ฟเวอร์ไปยังไคลเอ็นต์ ซึ่งถูกถ่ายโอนเป็นชิ้นๆ หรือไม่ เรากำลังพูดถึงข้อมูลจำนวนเท่าใด และเหตุใดลูกค้าจึงอ่านข้อมูลทั้งหมด

ฉันจะใช้ขั้นตอนการจัดเก็บเพื่อทำการสืบค้นในฐานข้อมูลและส่งคืนเฉพาะไคลเอนต์ที่เกี่ยวข้องออกจากคอลเลกชันได้อย่างไร

ไม่มีขั้นตอนการจัดเก็บใน MongoDB แต่คุณสามารถใช้ แผนที่ฝั่งเซิร์ฟเวอร์/ลดเพื่อ 'เข้าร่วม' คอลเลกชัน. โดยทั่วไปรหัสที่จัดเก็บและเรียกใช้โดยฐานข้อมูลถือเป็นการละเมิดการแยกข้อกังวลของสถาปัตยกรรมเลเยอร์ ฉันคิดว่ามันเป็นหนึ่งในแฮ็กที่น่าเกลียดที่สุดตลอดกาล - แต่ก็เป็นเรื่องที่ถกเถียงกันอยู่

นอกจากนี้ ยังเป็นที่ถกเถียงกันน้อยกว่า โปรดจำไว้ว่า M/R มีค่าใช้จ่ายจำนวนมากใน MongoDB และไม่ได้มุ่งเน้นไปที่การสืบค้นแบบเรียลไทม์ เช่น ในการเรียกเว็บเซิร์ฟเวอร์ การโทรเหล่านี้จะใช้เวลาหลายร้อยมิลลิวินาที

มีวิธีเขียนแบบสอบถามที่รวมผลลัพธ์จากคอลเลกชันอื่นหรือไม่?

ไม่ การดำเนินการถูกจำกัดไว้ที่คอลเลกชันเดียว คุณสามารถทำการสืบค้นครั้งที่สองและใช้ตัวดำเนินการ $in ที่นั่นได้ ซึ่งคล้ายกับการเลือกย่อยและรวดเร็วพอสมควร แต่แน่นอนว่าต้องใช้การไปกลับสองครั้ง

person mnemosyn    schedule 15.02.2015
comment
ขอบคุณมากสำหรับคำตอบของคุณ ฉันไม่ต้องการรวมพวกมันเข้ากับคอลเลกชันเดียวเนื่องจากเซิร์ฟเล็ตอื่น ๆ ที่ทำงานอยู่แล้ว วิธีการทำงานในขณะนี้คือ ฉันได้รับรายชื่อลูกค้าที่เกี่ยวข้องจากคอลเลกชันของลูกค้า และส่งรายการนี้ไปยังแบบสอบถามของการรวบรวมข้อมูลลูกค้า จากนั้นฉันจึงได้รับผลลัพธ์แบบรวมเท่านั้น ใช่ ฉันต้องการข้อมูล แต่ฉันต้องการตัดการรับและส่งรายชื่อลูกค้าจากและกลับไปยังเซิร์ฟเวอร์ ให้เซิร์ฟเวอร์ถามตัวเอง ให้แบบสอบถามของการรวบรวมข้อมูลลูกค้าเพื่อขอให้ลูกค้ารวบรวมสำหรับไคลเอนต์ที่เกี่ยวข้อง รายการ. - person Toda Raba; 17.02.2015
comment
โดยขั้นตอนที่ฉันหมายถึงฟังก์ชั่นจาวาสคริปต์ - person Toda Raba; 17.02.2015

ฉันจะใช้ขั้นตอนการจัดเก็บเพื่อทำการสืบค้นในฐานข้อมูลและส่งคืนเฉพาะไคลเอนต์ที่เกี่ยวข้องออกจากคอลเลกชันได้อย่างไร อีกทางหนึ่ง

ไม่มีขั้นตอนใน Mongodb

มีวิธีเขียนแบบสอบถามที่รวมผลลัพธ์จากคอลเลกชันอื่นหรือไม่

โดยปกติคุณไม่จำเป็นต้องเข้าร่วมใดๆ ใน MongoDB และไม่มีสิ่งนั้น ความยืดหยุ่นของเอกสารสามารถจัดการความต้องการในการรวมทั่วไปได้แล้ว คุณควรคิดถึงโมเดลเอกสารของคุณและถามวิธีการออกแบบการรวมจากสคีมาของคุณควรเป็นช่องทางแรกของคุณเสมอ คุณอาจจำเป็นต้องใช้ aggregationหรือ Map-Reduce ในฝั่งเซิร์ฟเวอร์เพื่อจัดการสิ่งนี้

person styvane    schedule 15.02.2015
comment
ไม่มีขั้นตอนการจัดเก็บที่คล้ายกับ SQL แต่มีวิธีจัดเก็บฟังก์ชันจาวาสคริปต์ที่คล้ายกับขั้นตอน ฉันแน่ใจว่า OP ต้องการทราบเกี่ยวกับเรื่องนี้ docs.mongodb.org/manual/tutorial/ - person mshthn; 15.02.2015
comment
@LaszloTenki คุณพูดถูกและอย่างที่ฉันพูดในคำตอบของฉันเขาสามารถใช้ Map-Reduce แทนในฝั่งเซิร์ฟเวอร์ - person styvane; 15.02.2015

ก่อนอื่น mnemosyn และ Michael9 นั้นถูกต้อง แต่ถ้าฉันเป็นเหมือนคุณ โดยสมมติว่าการรวบรวมข้อมูลลูกค้าเป็นหนึ่งเอกสารต่อลูกค้าหนึ่งราย ฉันจะจัดเก็บ ID เอกสารของเอกสารข้อมูลลูกค้าในเอกสารไคลเอนต์เพื่อทำให้ "เข้าร่วม" (ยังไม่มีการรวมใน Mongo) ง่ายขึ้น .

หากคุณมีเอกสารข้อมูลไคลเอนต์ต่อไคลเอนต์มากกว่า อาร์เรย์ของ ID เอกสาร

แต่ทั้งหมดนี้ไม่ได้ช่วยให้คุณประหยัดจากการที่คุณต้องใช้ "เข้าร่วม" ในโค้ดแอปพลิเคชันของคุณ หากเป็นแอป Rails ก็น่าจะอยู่ในคอนโทรลเลอร์ของคุณ

person mshthn    schedule 15.02.2015