วิธีการเข้าถึงคอลเลกชันที่มีมาก่อนกับพังพอน?


143

ฉันมีคอลเลกชันขนาดใหญ่ของ 300 วัตถุในฐานข้อมูลquestion testฉันสามารถโต้ตอบกับคอลเลคชันนี้ได้อย่างง่ายดายผ่านเชลล์แบบโต้ตอบของ MongoDB อย่างไรก็ตามเมื่อฉันพยายามรับคอลเลกชันผ่าน Mongoose ในแอปพลิเคชัน express.js ฉันได้รับอาร์เรย์ว่างเปล่า

คำถามของฉันคือฉันจะเข้าถึงชุดข้อมูลที่มีอยู่แล้วนี้แทนที่จะสร้างใหม่แบบด่วนได้อย่างไร นี่คือรหัสบางส่วน:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');
mongoose.model('question', new Schema({ url: String, text: String, id: Number }));

var questions = mongoose.model('question');
questions.find({}, function(err, data) { console.log(err, data, data.length); });

ผลลัพธ์นี้:

null [] 0

คำตอบ:


260

พังพอนเพิ่มความสามารถในการระบุชื่อคอลเลกชันภายใต้สคีมาหรือเป็นอาร์กิวเมนต์ที่สามเมื่อประกาศโมเดล มิฉะนั้นจะใช้เวอร์ชันพหูพจน์ที่กำหนดโดยชื่อที่คุณจับคู่กับโมเดล

ลองทำสิ่งต่อไปนี้ทั้งสคีมาแมป:

new Schema({ url: String, text: String, id: Number}, 
           { collection : 'question' });   // collection name

หรือโมเดลที่แมป:

mongoose.model('Question', 
               new Schema({ url: String, text: String, id: Number}), 
               'question');     // collection name

9
ฉันจะหาข้อมูลนี้ได้ที่ไหนในเอกสาร สิ่งนี้ช่วยได้มาก แต่ไม่มีที่ใดที่อธิบายถึงพหูพจน์
StudioWorks

สวัสดี @calvinfo ฉันจะเปลี่ยนชื่อคอลเลกชันที่รันไทม์ได้อย่างไร ฉันมี UserSchema 5 คอลเล็กชันและฉันต้องการตั้งชื่อให้แตกต่างกันเช่น users_server1, users_server2, users_server3 ...
Ragnar

1
Pleae ให้ตัวอย่างแบบสอบถามเช่นModel.collection.insert();..
Steve K

6
เหมือนกันที่นี่ฉันใช้เวลาหลายชั่วโมงในการหาปัญหานี้พบเอกสารที่นี่mongoosejs.com/docs/guide.html#collection
ElvinD

3
สิ่งนี้ได้ผลสำหรับฉัน ฉันมีคอลเล็กชันผู้ใช้ที่ฉันเก็บรวบรวมไว้ หากต้องการเข้าถึงมันด้วยพังพอนฉันทำmongoose.connect("mongodb://localhost/fromlab"); var Schema = mongoose.Schema; var User = mongoose.model("User", new Schema({}), "users"); User.find({}, function(err, doc){ console.log((doc)) })
แจ็คเปล่า

62

นี่คือสิ่งที่เป็นนามธรรมของคำตอบของ Will Nathan หากใครต้องการเพียงแค่ฟังก์ชั่น Add-in คัดลอกวางง่ายๆ

function find (name, query, cb) {
    mongoose.connection.db.collection(name, function (err, collection) {
       collection.find(query).toArray(cb);
   });
}

เพียงแค่ทำfind(collection_name, query, callback);เพื่อให้ได้ผลลัพธ์

ตัวอย่างเช่นถ้าฉันมีเอกสาร {a: 1} ในคอลเล็กชัน 'foo' และฉันต้องการแสดงรายการคุณสมบัติของเอกสารนั้นฉันจะทำสิ่งนี้:

find('foo', {a : 1}, function (err, docs) {
            console.dir(docs);
        });
//output: [ { _id: 4e22118fb83406f66a159da5, a: 1 } ]

สิ่งนี้มีประโยชน์มากเมื่อเรียกใช้การทดสอบการรวมบน API
Greg

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

27

คุณสามารถทำสิ่งนี้ได้มากกว่าที่คุณจะเข้าถึงฟังก์ชัน mongodb ดั้งเดิมภายในพังพอน:

var mongoose = require("mongoose");
mongoose.connect('mongodb://localhost/local');

var connection = mongoose.connection;

connection.on('error', console.error.bind(console, 'connection error:'));
connection.once('open', function () {

    connection.db.collection("YourCollectionName", function(err, collection){
        collection.find({}).toArray(function(err, data){
            console.log(data); // it will print your collection data
        })
    });

});

1
ตอบโจทย์เป๊ะ!
CandleCoder

15

ฉันมีปัญหาเดียวกันและสามารถเรียกใช้การสืบค้นแบบไม่ใช้สคีมาโดยใช้การเชื่อมต่อพังพอนที่มีอยู่ด้วยรหัสด้านล่าง ฉันได้เพิ่มข้อ จำกัด ง่ายๆ 'a = b' เพื่อแสดงตำแหน่งที่คุณจะเพิ่มข้อ จำกัด ดังกล่าว:

var action = function (err, collection) {
    // Locate all the entries using find
    collection.find({'a':'b'}).toArray(function(err, results) {
        /* whatever you want to do with the results in node such as the following
             res.render('home', {
                 'title': 'MyTitle',
                 'data': results
             });
        */
    });
};

mongoose.connection.db.collection('question', action);

1
นี่คือสิ่งที่ฉันกำลังมองหาเพราะพังพอนไม่มีการรองรับ gridFS ใด ๆ ฉันใช้วิธีนี้เพื่อดึงข้อมูลเมตาของไฟล์จาก gridfs (gridstore) เพียงแค่แทนที่questionในโค้ดด้านบนfs.filesและคุณก็พร้อมที่จะไป
k00k

7

แน่ใจหรือว่าคุณเชื่อมต่อกับฐานข้อมูล (ฉันถามเพราะฉันไม่เห็นพอร์ตที่ระบุ)

ลอง:

mongoose.connection.on("open", function(){
  console.log("mongodb is connected!!");
});

นอกจากนี้คุณสามารถ "แสดงคอลเลกชัน" ใน mongo shell เพื่อดูคอลเลกชันภายในฐานข้อมูลของคุณ - อาจลองเพิ่มบันทึกผ่านพังพอนและดูว่ามันไปสิ้นสุดที่ใด?

จากรูปลักษณ์ของสตริงการเชื่อมต่อของคุณคุณควรเห็นบันทึกในฐานข้อมูล "test"

หวังว่าจะช่วยได้!


4
ที่น่าสนใจคือการจัดเก็บข้อมูลในquestionsคอลเล็กชันเมื่อข้อมูลที่ฉันพยายามเข้าถึงอยู่ในquestionคอลเล็กชัน พังพอนทำพหูพจน์โดยอัตโนมัติชื่อคอลเลกชัน / รุ่น
theabraham

ใช่ฉันคิดว่ามัน ... ฮ่า! ฉันเพิ่งเริ่มต้นด้วยตัวเองดังนั้นฉันจึงไม่ได้สำรวจทุกซอกทุกมุม ... แต่ฉันจำได้ว่าเมื่อเห็นเกาลัดลีแอลเป็นลมขณะที่ฉันหมุนผ่าน Google Groups
จับ

4

อย่างอื่นที่ไม่ชัดเจนสำหรับฉันอย่างน้อยก็คือเมื่อใช้พารามิเตอร์ที่สามของ Mongoose เพื่อหลีกเลี่ยงการแทนที่คอลเล็กชันจริงด้วยชื่อใหม่ที่มีชื่อเดียวกันnew Schema(...)อันที่จริงเป็นเพียงตัวยึดตำแหน่งและไม่รบกวนการมีอยู่ schema ดังนั้น

var User = mongoose.model('User', new Schema({ url: String, text: String, id: Number}, { collection : 'users' }));   // collection name;
User.find({}, function(err, data) { console.log(err, data, data.length);});

ทำงานได้ดีและส่งคืนฟิลด์ทั้งหมดแม้ว่า Schema จริง (ระยะไกล) จะไม่มีฟิลด์เหล่านี้เลยก็ตาม พังพอนจะยังคงต้องการมันเหมือนnew Schema(...)เดิมและตัวแปรแทบจะไม่แฮ็คมัน


1
มันให้ข้อผิดพลาด 'ชื่อคอลเลกชันต้องเป็นสตริง' สำหรับฉันแก้ไข: เป็นคำตอบของ 'calvinfo' หากคุณต้องการให้ชื่อคอลเลกชันในตัวสร้างแบบจำลองคุณเพียงแค่ส่งชื่อคอลเลกชันในรูปแบบสตริงไม่ใช่โมเดลวัตถุ ดังนั้นคำตอบของคุณจะเป็นจริงหากแก้ไขเช่นนี้ var User = mongoose.model ('User', สคีมาใหม่ ({url: String, text: String, id: Number}, 'users')); // ชื่อคอลเลกชัน; User.find ({}, function (err, data) {console.log (err, data, data.length);});
Kaan Erkoç
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.