即使有效的id,Mongoose findById也返回null

时间:2017-12-15 07:06:49

标签: node.js mongodb mongoose

我已经看到了关于以下类似标题的讨论 mongoose 'findById' returns null with valid id 但我的问题不是数据库名称,因为所有与同一数据库的其他连接实际上对同一个集合的查询工作正常。 我使用的是mongoose 4.13.6,节点js 6.11和mongo 3.4。 这是一个帖子请求。

var query=req.body;

我将搜索参数发送为

var findFruit = 
{
    _id:query._id
}

当我打印我的findFruit时,我得到:

_id:'5a1cf77920701c1f0aafb85e'

控制器功能是:

Fruit.findById(findFruit._id,function(err,fruit){
        if( _.isNull(err) ){
            var response = genRes.generateResponse(true,"found successfully");
            callback(response);
        }
        else{
            var response = genRes.generateResponse(false,"there occured some error : "+err);
            callback(response);
        }
    })

我甚至试过找

Fruit.find(findFruit,function(err,fruit){
        if( _.isNull(err) ){
            var response = genRes.generateResponse(true,"found successfully");
            callback(response);
        }
        else{
            var response = genRes.generateResponse(false,"there occured some error : "+err);
            callback(response);
        }
    })

该集合肯定有此ID下的条目。

我也经历过这个git问题https://github.com/Automattic/mongoose/issues/3079 不幸的是,我不能降级mongoose,因为它可能会影响其他多个工作功能。 编辑: 我尝试创建ObjectId,如:

var mongoose = require('mongoose');
var ObjectID = require('mongodb').ObjectID;
var objectId = new ObjectID();
// Convert the object id to a hex string
var originalHex = objectId.toHexString();
// Create a new ObjectID using the createFromHexString function
var newObjectId = new ObjectID.createFromHexString(query._id);

模型文件:

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

var FruitSchema = new Schema({
    name : {type : String, unique : true},
    color : {type : String}
});

module.exports = mongoose.model('Fruit', FruitSchema);

4 个答案:

答案 0 :(得分:3)

我所有的findById(“ id”)调用均返回null。

使用Compass查看集合时,我意识到我所有的_id元素都是Strings。请注意,整个集合已导入。

我在Compass中创建了一个新元素,并且_id被创建为ObjectId!当我使用该元素的ID调用findById(“ id”)时,它就起作用了!

我的结论是,导入显然存在一个错误。我还没有找到在实际集合中将字符串_id字段转换为ObjectId的方法。

答案 1 :(得分:1)

  

当_id元素为字符串时,我所有的findById(“ id”)调用均返回null。

首先:

检查您的mongodb数据库,如果_id存储为String,则findById(id)找不到,因为它标识了ObjectId。如果您通过使用mongoimport命令并在JSON中包含_id来使用导入数据库:

  • 解决方案1:

    修改您的JSON,并为每个文档更改_id例如:

    _id: "5a68fde3f09ad7646ddec17e"执行以下操作,然后再次运行mongoimport

    "_id": { "$oid": "5a68fde3f09ad7646ddec17e" }
  • 解决方案2:

    在JSON文件中删除_id,删除collection并再次导入。 Mongo将自动创建_id。

完成上述任何一种解决方案后,findById("id")将起作用。

其次:

尤其是在您的_id元素为字符串的情况下,使用mongodb包可能是一个更好的主意:npm i mongodb

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";

MongoClient.connect(url, function (err, db) {
    if (err) throw err;
    var dbo = db.db("your_db_name");
    dbo.collection("fruits_collection")
       .find({_id:'5a1cf77920701c1f0aafb85e'})
       //.find({_id:'5a1cf77920701c1f0aafb85e'}, { projection: { _id: 0, name: 1, color: 1} }) // to select specific columns desired
      .toArray(function (err, result) {
           if (err) throw err;
           console.log(result);
           db.close();
    });
});

上面的简单代码假设您自己通过try-catch或 发送404作为状态代码,或重定向到错误页面模板,具体取决于代码是否嵌入在Express路由处理程序中。

希望这对您有所帮助..:)

答案 2 :(得分:0)

还在试图找出为什么findById对我不起作用,但下面的代码就是这样做了

var mongoose = require('mongoose');
var newObjectId=new mongoose.Types.ObjectId(query._id);
var params={
            '_id':newObjectId
}
Fruit.find(params).exec(function (err,fruit) {
if( _.isNull(err) ){
        var response = genRes.generateResponse(true,"found successfully");
        callback(response);
    }
    else{
        var response = genRes.generateResponse(false,"there occured some error : "+err);
        callback(response);
    }
})

答案 3 :(得分:0)

@Shoom。是的,为我工作,谢谢。 findById()需要ObjectID,而不是字符串。

我没有创建具有特定ID的文档的约束,因此我导入时没有_id。数据库具有新分配的_id作为ObjectID。

findById(id)(和updateOne({_id:id},...),按预期开始工作。