简体   繁体   中英

Node.js find result by ID from mongoDB

I am new in Node.js so sorry if this is really stupid question but however I try I can't find the answer.

I have some simple code:

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);

This should return some data I insert to mongo DB, while first one /people/ return everything correctly (basicly just return dump of DB)

The second one with ID return nothing. I try to debug it and I see that inside of function ID is defined correctly, I also used ID which comes from "people" site (something like : 55e028081181bfdd8a7972d2 ), dispite this fact I am not able to get any answer or error.

Is there a chance someone can advise me where can be a problem?

It's time this question was debunked, as I myself am very much getting tired of the false responses here.

The code as a unit is fine. The only problems that can be occuring are that you are sending the wrong things or have the wrong collection addressed, as well as one last issue concerning the _id value itself.

You need nothing other than "raw" express and mongoose for this to work, as my listing proves:

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");

    }
  );

});

Which gives output like:

Created and call in URL: 55e0464e66e13f6506e8e38e
ready

So when you call the server on the /people url you get:

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

As a response.

And when you call with the id as in /people/55e0464e66e13f6506e8e38e then you get:

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

As expected.

So if your application is not working then you are either not sending in what you think you are, or you actually have a String for the _id value in the collection, or it is completely mismatched in the collection or database name. All urls should work, and if none are working then the latter is the case.

In the case of the _id being a string, then the schema is wrong and needs to be:

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

Where most importantly, apart from setting the correct type for the _id field in the schema is also the { "_id": false } .

This is because you need this to tell mongoose to not attempt to parse the "string" into an ObjectId as it always does by default.

Without that setting a "string" will always fail.

But this listing is the proof of what does work, and also the only change really needed if in fact the _id contains a "string" or other type. So if a Number then both set the schema for _id: Number and also { "_id": false } otherwise the same failure reasons occur.


For pure silliness then change my listing to :

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

And watch it work every time also.

And please also remove the { "_id": false } and watch it fail so it becomes clear why this is required when the _id type is meant to be overridden.

If you have populated your database from outside mongoose, there's a chance you have changed the type of the _id property. If that's the case try adding _id to your schemma as follows:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM