简体   繁体   English

节点,猫鼬,Express-具有ID的REST api GET子文档

[英]Node, Mongoose, Express - REST api GET subdocument with id

Thought I'd check out node a couple days back and decided to create a simple API as an introduction to the platform. 以为我会在几天前结帐节点,并决定创建一个简单的API作为平台的介绍。 I am using node with express and mongoose. 我正在使用Express和猫鼬的节点。 My issues at the moment revolve around trying to get a single subdocument from an array of subdocuments in my primary document. 目前,我的问题围绕着尝试从主文档中的一系列子文档中获取单个子文档的问题。

My app has a simple structure. 我的应用程序结构简单。 I have three models: place, address, and people. 我有三种模型:地点,地址和人。 Each place embeds many addresses, and each address embeds many people (I picked this to get practice on subdocuments, and sub-subdocuments). 每个地方都嵌入了许多地址,每个地址都嵌入了许多人(我选择这样做是为了获得有关子文档和子子文档的练习)。 The models themselves are separated into their own files as such: 模型本身被分成自己的文件,如下所示:

./models/place.js ./models/place.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var AddressSchema = require('./address')

var PlaceSchema = new Schema({
    name: String,
    addresses: [AddressSchema.Schema]
});

module.exports = mongoose.model('Place', PlaceSchema);

.models/address.js .models / address.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PersonSchema = require('./person');

var AddressSchema = new Schema({
    street: String,
    city: String,
    state: String,
    zip: Number,
    people: [PersonSchema.Schema]
});

module.exports = mongoose.model('Address', AddressSchema);

.models/person.js .models / person.js

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

var PersonSchema = new Schema({
    name: String,
});

module.exports = mongoose.model('Person', PersonSchema);

As we can see, a place can contain an array of addresses, and each address can contain an array of people. 如我们所见,一个地点可以包含一个地址数组,每个地址可以包含一个人数组。

Now as far as the my actual routes are concerned, I have no issue adding places, and adding addresses to places (I haven't drilled down to the person level as of yet). 现在,就我的实际路线而言,我没有问题添加地点,并向地点添加地址(到目前为止,我还没有深入到人员级别)。 The issue I am having is trying to get a single address. 我遇到的问题是试图获得一个地址。 I am thinking once I receive a single address, I can next assign a bunch of people to that address. 我在想,一旦我收到一个地址,接下来我就可以将一堆人分配给该地址。

Here is the route that is causing trouble: 这是引起麻烦的路线:

router.route('/places/:place_id/addresses/:address_id')

    .get(function(req, res) {
        Place.findById(req.params.place_id, function(err, place) {
            if (err)
                res.send(err);
            res.json(place.addresses.id(req.params.address_id));
        });
    });

From the mongoose docs, it looks like the .id() method is the goto in this situation, but I get a "TypeError" when doing this, with logs saying that the object has no method 'id'. 从猫鼬文档来看,在这种情况下,.id()方法看起来像是goto,但这样做时却出现“ TypeError”,日志显示该对象没有方法“ id”。

On the other hand, I am having zero issue getting all the addresses of a single place: 另一方面,获取单个位置的所有地址的问题为零:

router.route('/places/:place_id/addresses') 

    .get(function(req, res) {
        Place.findById(req.params.place_id, function(err, place) {
            if (err)
                res.send(err);
            res.json(place.addresses);
        });
    })

I also have zero issue creating and saving places, creating and saving addresses to a place, etc. 创建和保存地点,创建和保存地址到地点等也没有问题。

I've tried to dig and find others with a similar issue. 我试图挖掘并找到其他遇到类似问题的人。 I've found others who have experienced the same type error, but typically it has had to do with the order of initialization of their models. 我发现其他人也遇到过相同的类型错误,但通常与模型初始化的顺序有关。 Most seem to be initializing their models in one big document, in which order of initialization is important. 多数人似乎是在一个大文件中初始化其模型,而初始化的顺序很重要。 I do not understand how that would be an issue here? 我不明白这里会是什么问题?

Hopefully this is just me doing something stupid as I'm pretty stumped. 希望这只是我做的愚蠢的事情,因为我很沮丧。 Any help is very much appreciated. 很感谢任何形式的帮助。

EDIT---------------------------------------------------------------------------------------------- 编辑 - - - - - - - - - - - - - - - - - - - - - - - - - ---------------------------------------------

I'm thinking my problems are revolving around the id value of my :address_id parameter in the GET request above. 我认为我的问题围绕上述GET请求中的:address_id参数的id值。

Taking some inspiration from this post: 从这篇文章中得到一些启发:

MongoDB, Mongoose: How to find subdocument in found document? MongoDB,Mongoose:如何在找到的文档中找到子文档?

I updated my get function to the following (though I do not know why what I had initially isn't working): 我将get函数更新为以下内容(尽管我不知道为什么最初的内容无法正常工作):

router.route('/places/:place_id/addresses/:address_id')

    .get(function(req, res) {
        Place.findById(req.params.place_id, function(err, place) {
            if (err)
                res.send(err);

            var address = place.addresses.filter(function (address) {
                    return address._id === req.params.address_id;
             }).pop();

            res.json(address);
        });
    });

If instead of ._id I use .city for example to filter my addresses, then I return the correct addresses in the total array. 如果我使用.city代替._id来过滤我的地址,那么我将在总数组中返回正确的地址。 Obviously this is not what I'm looking for. 显然,这不是我想要的。 I'd like the return an address based on its ID. 我想根据其ID返回一个地址。

Any help is appreciated. 任何帮助表示赞赏。

In Mongoose there is a difference between the MongooseArray type and the MongooseDocumentArray type, which has the id() method you are looking for. 在Mongoose中, MongooseArray类型和MongooseDocumentArray类型之间存在区别,后者具有您要查找的id()方法。

I was able to get your code working by moving the AddressSchema into the same file as PlaceSchema . 通过将AddressSchema移到与PlaceSchema相同的文件中,我可以使您的代码正常工作。

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

var AddressSchema = Schema({
    street: String,
    city: String,
    state: String,
    zip: Number
});

var PlaceSchema = Schema({
    name: String,
    addresses: [AddressSchema]
});

module.exports = mongoose.model('Place', PlaceSchema);

Now the callback from Place.findById(...) shows place.addresses as a DocumentArray and the individual subdocuments are listed as an EmbeddedDocument . 现在,从回调Place.findById(...)表示place.addresses作为DocumentArray和单独的子文档被列为EmbeddedDocument

I also moved the schemas back to their separate files. 我还将模式移回了它们各自的文件。 This time I made sure to export the schema instead of the model. 这次,我确保导出模式而不是模型。 This also works. 这也有效。

Inspecting the code further I have found the problem! 进一步检查代码,我发现了问题!

You are referencing Address.Schema . 您正在引用Address.Schema This should be Address.schema (note the lower case). 这应该是Address.schema (注意小写)。 Since Address.Schema is undefined , mongoose was accepting anything. 由于Address.Schema undefined ,所以猫鼬可以接受任何东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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