【问题标题】:Node.js find result by ID from mongoDBNode.js 通过 mongoDB 的 ID 查找结果
【发布时间】:2015-11-22 22:21:27
【问题描述】:

我是 Node.js 的新手,如果这是一个非常愚蠢的问题,我很抱歉,但是我尝试找不到答案。

我有一些简单的代码:

var express = require("express");
var mongoose = require("mongoose");
var cors = require("cors");

mongoose.connect('mongodb://localhost/simple')

var personSchema = {
    firstName:String,
    lastName:String,
    email:String
}

var Person = mongoose.model('Person', personSchema, 'people')

var app = express();
app.use(cors());

app.get('/people', function (req, res) {
    Person.find(function (err, doc) {
        res.send(doc);
    })
})

app.get('/people/:id', function (req, res) {
    Person.findById(req.params.id, function (err, doc) {
        res.send(doc);
    })
})
app.listen(3000);

这应该返回我插入到 mongo DB 的一些数据,而第一个 /people/ 正确返回所有内容(基本上只是返回 DB 的转储)

具有 ID 的第二个不返回任何内容。我尝试调试它,我看到函数 ID 的内部定义正确,我还使用了来自“人”网站的 ID(类似于:55e028081181bfdd8a7972d2),尽管这个事实我无法得​​到任何答案或错误.

有没有人可以告诉我哪里有问题?

【问题讨论】:

  • 您是否尝试使用 ObjectId 构造函数,例如 stackoverflow.com/questions/6578178/…
  • 我不知道你是什么意思,你的意思是不是像:pastebin.com/nFxSrZqw 如果是的,不幸的是它对我不起作用:(
  • MongoDB 是否已使用您的应用程序以及通过 mongoose 或任何其他方法填充了数据?
  • 请分享其外观的示例数据。
  • 我同意这一点。在您的“人员”集合中显示数据。 mongoose.model 调用中的第三个参数是不需要的,因为这是它所期望的(person 的复数形式是 people)。

标签: javascript node.js mongodb


【解决方案1】:

如果您从 mongoose 外部填充了您的数据库,那么您有可能更改了 _id 属性的类型。如果是这种情况,请尝试将 _id 添加到您的架构中,如下所示:

var personSchema = {
    firstName:String,
    lastName:String,
    email:String,
    _id:String
}

【讨论】:

  • 嗯。 .findById() 是一种猫鼬方法。并且Person模型已经明确定义了。
  • @BlakesSeven 是的,根据开头的问题:这应该返回一些我插入到 mongo DB 的数据,这表明数据和架构是手动创建的或由其他一些人创建的系统。
  • 但是你的“答案”?甚至与此无关。在我和其他人对此投反对票之前,我只是警告你。哦。 mongoose 将“id”和“_id”视为同一事物。所以你显然不知道材料,只是在网上搜索。大多数人都能做到。只是为了让您知道为什么会发生反对票。
  • @BlakesSeven。我正在回答有关如何使用 mongoose 从 MongoDB 读取预先存在的文档的问题,因为我知道他在问这个问题。我可能错了,但他分享的代码肯定是只读的,所以我猜他当前的文档没有_id 属性。
  • @BlakesSeven 让您(和其他所有人)知道我已经针对我的 MongoLabs 帐户在本地执行了他的代码,添加了一个 POST 端点以在发布我的答案之前创建新条目。它工作得很好
【解决方案2】:

是时候揭穿这个问题了,因为我自己已经厌倦了这里的错误回答。

作为一个单元的代码很好。可能发生的唯一问题是您发送了错误的内容或处理了错误的集合,以及与 _id 值本身有关的最后一个问题。

正如我的清单所证明的那样,您只需要“原始”快递和猫鼬就可以了:

var async = require('async'),
    express = require('express'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/simple');

var personSchema = new Schema({
  firstName: String,
  lastName: String,
  email: String
});

var Person = mongoose.model( 'Person', personSchema );

var app = express();

mongoose.connection.on('open',function(err) {

  async.series(
    [
      function(callback) {
        Person.remove({},callback);
      },
      function(callback) {
        Person.create({
          firstName: "John",
          lastName: "Doe",
          email: "john.doe@example.com"
        },callback);
      }
    ],
    function(err,results) {
      if (err) throw err;
      console.log(
        "Created and call in URL: %s",
        results[1]._id
      );

      // setup routes

      app.get('/people', function(req,res) {
        Person.find(function(err,docs) {
          res.send(docs)
        });
      });

      app.get('/people/:id', function(req,res) {
        Person.findById(req.params.id,function(err,doc) {
          res.send(doc);
        });
      });

      app.listen(3000);
      console.log("ready");

    }
  );

});

输出如下:

Created and call in URL: 55e0464e66e13f6506e8e38e
ready

所以当你在/people url 上调用服务器时,你会得到:

[
    {
        "_id":"55e0464e66e13f6506e8e38e",
        "firstName":"John",
        "lastName":"Doe",
        "email":"john.doe@example.com",
        "__v":0
    }
]

作为回应。

当您使用/people/55e0464e66e13f6506e8e38e 中的 id 调用时,您会得到:

{
    "_id":"55e0464e66e13f6506e8e38e",
    "firstName":"John",
    "lastName":"Doe",
    "email":"john.doe@example.com",
    "__v":0
}

正如预期的那样。

因此,如果您的应用程序无法正常工作,那么您要么没有发送您认为的内容,要么您实际上在集合中有一个 _id 值的字符串,或者它在集合或数据库名称中完全不匹配.所有 url 都应该工作,如果没有工作,那么后者就是这种情况。

如果_id是一个字符串,那么架构是错误的,需要是:

var personSchema = new Schema({
  _id: String
  firstName: String,
  lastName: String,
  email: String
},{ "_id": false });

最重要的是,除了为架构中的_id 字段设置正确的类型之外,还有{ "_id": false }

这是因为您需要它来告诉 mongoose不要尝试将“字符串”解析为 ObjectId,就像默认情况下所做的那样。

如果不设置“字符串”将始终失败。

但这个清单是有效的证明,也是如果事实上_id 包含“字符串”或其他类型时真正需要的唯一更改。因此,如果Number 则同时为_id: Number{ "_id": false } 设置架构,否则会出现相同的失败原因。


为了纯粹的愚蠢,请将我的列表更改为:

var personSchema = new Schema({
  _id: { type: String, default: "55e0464e66e13f6506e8e38e" }, 
  firstName: String,
  lastName: String,
  email: String
},{ "_id": false });

并且每次都观察它的工作。

还请删除 { "_id": false } 并观察它是否失败,以便清楚为什么当 _id 类型要被覆盖时需要这样做。

【讨论】:

  • 你自然是对的,body-parser 帮助处理 put 和 post 请求,其中 json 数据作为 req.body 发送。
  • @PavelGatnar 好吧,既然 POST 数据在“正文”中,那么您需要在这里做一些事情,或者手动处理。此请求位于 URL 中,因此req.params 始终可以访问。代码在这里供人们复制。此处还列出了可能失败的原因(全部)。
  • 正如你所料,当我打开 /people/ 时,这会返回正确的值,但我对这段代码有点困惑。我是否正确理解您删除之后的所有内容,添加一行?因为如果是的话,它没有帮助。我需要 /people/ 返回所有值,而 /people/id/ 只返回带有 ID 的值:)
  • @Andurit 我将此作为“自包含示例”提交给其他人和您自己“一遍又一遍”地为自己运行,并获得相同的可重复结果。因此,在我开始定义路由之前发生的事情通常不适用于您自己的代码。但原则是。我基本上是在创建具有我期望的结构的东西,然后发出与您完全相同的方法调用。因此,正如我所说,您拥有的代码没有问题。只是输入或数据与您的要求和期望不符。
  • 感谢您的解释,有机会我们可以在聊天中讨论一下吗?我想知道更多细节:) p.s。将您的答案标记为正确
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 2016-02-07
  • 2018-07-29
  • 2019-11-08
  • 1970-01-01
相关资源
最近更新 更多