MongoDB 2.0.0 驱动程序,按 ID 检索记录问题

MongoDB 2.0.0 Driver, Issue Retrieving Records By ID

我正在尝试使用 MongoDB 2.0.0 驱动程序在 NodeJS/Express 中构建一个简单的 Web 服务。

更新:根据之前的反馈,我删除了我拥有的 db.close() 并重新安排了我的代码

当我执行我的 GET all(无过滤器)方法或我的 POST 或 PUT 方法时,一切都按预期工作。

但是,如果我执行 GET(特定)方法,我会收到如下错误:

---------------------------------------------------------------

Connected to MongoDB: mongodb://localhost:27017/example
Request URL: /jobs/profileID/1QtG8i88Sq
Method: GET [Retrieve Specific]
Collection: jobs
Filter: {"profileID":"1QtG8i88Sq"}

Error
    at Error.MongoError (/apps/services.example.org/node_modules/mongodb/node_modules/mongodb-core/lib/error.js:13:17)
    at Collection.find (/apps/services.example.org/node_modules/mongodb/lib/collection.js:269:11)
    at /apps/services.example.org/index.js:80:35
    at Layer.handle [as handle_request] (/apps/services.example.org/node_modules/express/lib/router/layer.js:82:5)
    at next (/apps/services.example.org/node_modules/express/lib/router/route.js:110:13)
    at jsonParser (/apps/services.example.org/node_modules/body-parser/lib/types/json.js:96:40)
    at Layer.handle [as handle_request] (/apps/services.example.org/node_modules/express/lib/router/layer.js:82:5)
    at next (/apps/services.example.org/node_modules/express/lib/router/route.js:110:13)
    at Route.dispatch (/apps/services.example.org/node_modules/express/lib/router/route.js:91:3)
    at Layer.handle [as handle_request] (/apps/services.example.org/node_modules/express/lib/router/layer.js:82:5)

下面是我的 index.js 文件:

var error404 = 'http://example.org/404';
var expressPort = 8080;
var mongoConnectionString = 'mongodb://localhost:27017/example';
var mongoConnectedMessage = '\n---------------------------------------------------------------\n\nConnected to MongoDB: ' + mongoConnectionString;

/* ------------------------------------------------------------------------- */

var assert = require('assert');
var express = require('express');
var http = require('http');
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json();
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var MongoClient = require('mongodb').MongoClient;

// Configure Express 
var app = express();
app.set('port', process.env.PORT || expressPort); 
app.use(bodyParser.json());

// Configure CORS (Cross-Origin Resource Sharing) Headers 
app.all('*', function(request, response, next) {
   response.header("Access-Control-Allow-Origin", "*");
   response.header("Access-Control-Allow-Headers", "X-Requested-With");
   response.header('Access-Control-Allow-Headers', 'Content-Type');
   next();
});


/* ------------------------------------------------------------------------- */

MongoClient.connect(mongoConnectionString, function(error, db) {
    assert.equal(null, error);

    // Create
    app.post('/:collection', urlencodedParser, function(request, response) {
        if (IsValidRequest(request.url)) {
            var requestBody = request.body;
            var mongoCollection = request.params.collection;
            console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: POST [Create] \nCollection: ' + mongoCollection + '\n');
            db.collection(mongoCollection).insertOne(requestBody, function(error, documents) {
                if (error) {
                    console.log(error);
                    response.status(400).send(error); 
                } 
                else { 
                    response.status(201).send(documents);
                }
                return;
            });
        }
    });


    // Retrieve (All)
    app.get('/:collection', jsonParser, function(request, response) {
        if (IsValidRequest(request.url)) {
            var mongoCollection = request.params.collection;
            console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: GET [Retrieve All] \nCollection: ' + mongoCollection + '\n');
            db.collection(mongoCollection).find({}).toArray(function(error, documents) {
                if (error) { 
                    console.log(error);
                    response.status(400).send(error); 
                } 
                else { 
                    response.status(201).send(documents);
                }
                return;
            });
        }
    });


    // Retrieve (Specific)
    app.get('/:collection/:identifier/:value', jsonParser, function(request, response) {
        if (IsValidRequest(request.url)) {
            var mongoCollection = request.params.collection;
            var filter = '{"'+request.params.identifier+'":"'+request.params.value+'"}';
            console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: GET [Retrieve Specific] \nCollection: ' + mongoCollection + '\nFilter: ' + filter + '\n');
            db.collection(mongoCollection).find(filter).toArray(function(error, documents) {
                if (error) { 
                    console.log(error);
                    response.status(400).send(error); 
                } 
                else { 
                    response.status(201).send(documents);
                }
                return;
            });
        }
    });


    // Update
    app.put('/:collection/:identifier/:value', urlencodedParser, function(request, response) {
        if (IsValidRequest(request.url)) {
            var requestBody = request.body;
            var mongoCollection = request.params.collection;
            var filter = '{"'+request.params.identifier+'":"'+request.params.value+'"}';
            console.log(mongoConnectedMessage + '\nRequest URL: ' + request.url + '\nMethod: PUT [Update Specific] \nCollection: ' + mongoCollection + '\nFilter: ' + filter + '\n');
            db.collection(mongoCollection).findOneAndUpdate(filter, {$set: requestBody}, {
                returnOriginal: false,
                upsert: false
            }, function(error, documents) {
                if (error) { 
                    console.log(error);
                    response.status(400).send(error); 
                } 
                else { 
                    response.status(201).send(documents);
                }
                return;
            });
        }
    });

    // If all else fails...
    app.use(function (request, response) {
        response.redirect(error404);
    });
});




/* ------------------------------------------------------------------------- */

http.createServer(app).listen(app.get('port'), function(){
    console.log('Express Server Port: ' + app.get('port'));
});

/* ------------------------------------------------------------------------- */

function IsValidRequest(url) {
    //console.log('URL: ' + url);
    if (url !== '/favicon.ico') {
        return true;
    }
    else {
        return false;
    }
}

下面是我的示例数据,由 GET all(无过滤方法)返回:

[{"_id":"5503bb957e4eacd821b5c046","profileID":"1QtG8i88Sq","organization":"Acme Corp","title":"Sample Job","description":"Pellentesque vel turpis quis urna venenatis malesuada eu sit amet mi. Vivamus sit amet enim vitae sem convallis egestas. Nunc ac dui ac est euismod finibus id ut nulla. Donec malesuada ex risus, quis tincidunt dui semper eget. Proin eleifend, lectus consectetur sodales maximus, urna est malesuada eros, a pharetra metus mauris vitae felis. Vestibulum sit amet nisi euismod, pellentesque nunc sit amet, commodo nibh. Sed dignissim nunc nec diam pretium placerat. Nulla pellentesque nulla et varius molestie. Donec pulvinar, libero non placerat scelerisque, urna metus tincidunt nibh, suscipit aliquam felis mi non tortor. Sed et urna dolor. Nunc posuere arcu id sapien egestas dapibus. Sed ac est quis nunc rutrum tristique euismod pellentesque nibh.\n\nPellentesque vitae tempor elit. Ut urna arcu, aliquet nec turpis commodo, posuere facilisis purus. Phasellus ac tempus lacus, vel hendrerit lacus. Morbi porta mollis commodo. Mauris pellentesque justo eu enim sagittis, sit amet varius eros dapibus. Cras congue porttitor facilisis. Nunc rutrum nibh arcu, non eleifend nibh consectetur ac. Ut orci leo, vehicula eget efficitur quis, lobortis ut dolor. Morbi eu justo tristique, lobortis arcu eget, consectetur quam. Sed eget elementum est.","hireType":"Permanent","telecommute":"No","travel":"Yes - Part Time","hourlyPayRangeLow":"50","hourlyPayRangeHigh":"75","city":"Phoenix","stateProvince":"AZ","linkedInUrl":"","url":"https://careers.acmecorp.com/sample-job","email":"careers@acmecorp.com","phone":"","isActive":"true","dateCreated":"2015-03-14T04:39:45.711Z","dateModified":"2015-03-14T04:39:45.711Z"}]

这里的 "main" 问题是 filter 这里是 "string" 而不是查询 "object"。你应该像这样构造它:

var filter = {};
filter[request.params.identifier] = request.params.value;

就是说,您的问题的标题似乎是关于在查询中使用 ObjectId,因此如前所述,您需要 "cast" 自 "string"在请求中将不会匹配:

var ObjectID = require('mongodb').ObjectID;

var filter = {};
filter[request.params.identifier] = 
    ( request.params.identifier == "_id" ) ?
    new ObjectID(request.params.value) :
    request.params.value;

或者考虑到您字段的 "mapping" 与它们实际存储的 "type" 类似的一些逻辑。但同样值得注意的是,您的实际数据似乎没有实际的 ObjectId() 类型或任何其他特定类型。但是你需要在它该做的地方做这样的事情。

您的代码中还有其他您确实不应该做的事情,例如:

 db.collection(mongoCollection).findOneAndUpdate( // bad!

这并不安全,因为无法真正保证 collection 确实存在。你也最好这样写:

db.collection(mongoCollection,function(err,collection) {

    collection.findOneAndUpdate(filter,{ "$set": requestBody },function(err,doc) {

请注意,您指定的 "options" 无论如何都是默认值。

这应该能让你继续,但如果你 运行 遇到更多问题,那么你真的需要问另一个问题,而不是继续添加到现有问题中,指出问题或给出与问题相关的答案您当时提出的实际问题。

另请注意,您引用的语法来自 Node driver 2.0.x series, so make sure you have that version installed or otherwise use the methods as described in the 1.4.x series documentation

在这里提问不是好的行为,"I have this problem, thanks",然后 "Oh but now I got this other error when I changed it." 正如您在这里所做的那样。

也将您的问题分成小部分,并专注于具体问题。扔掉你的整个列表肯定会到处都有多个问题,而且通常范围太广,人们无法回答。