1

我真的是 Node 新手,但我目前有一个 NodeJS / Express 开源 CMS,并且想为我正在工作的应用程序输出一些 API 数据。如果我没有使用正确的术语或诸如此类的东西,请原谅我,这对我来说是新的。

我目前拥有的是两个系列,地点和旅游。CMS 允许我在两者之间建立关系。这只是将 ObjectID 的数组存储在每个关联的游览记录的位置记录中。

我想要做的是获取我的 API 输出代码(如下)并让它输出整个 tours 数组,并在每个位置记录中完成所有字段(标题、描述等)。目前它只输出一个 ID 数组。

这是我当前的代码:

var async = require('async'),
 landmark = require('keystone');

var Location = keystone.list('Location'),
        Tour = keystone.list('Tour');

    /**
     * List Locations
     */
    exports.list = function(req, res) {
        Location.model.find(function(err, items) {

            if (err) return res.apiError('database error', err);

            res.apiResponse({
                locations: items
            });

        });
    }

    /**
     * Get Location by ID
     */
    exports.get = function(req, res) {
        Location.model.findById(req.params.id).exec(function(err, item) {

            if (err) return res.apiError('database error', err);
            if (!item) return res.apiError('not found');

            res.apiResponse({
                location: item
            });

        });
    }

当前 API 输出(截断):

{
  "locations": [
    {
      "_id": "53a47997ebe91d8a4a26d251",
      "slug": "test-location",
      "lastModified": "2014-06-20T20:19:14.484Z",
      "commonName": "test location",
      "__v": 3,
      "url": "",
      "tours": [
        "53a47963ebe91d8a4a26d250"
      ],
      "images": []
    }
  ]
}

我在找什么:

{
  "locations": [
    {
      "_id": "53a47997ebe91d8a4a26d251",
      "slug": "test-location",
      "lastModified": "2014-06-20T20:19:14.484Z",
      "commonName": "test location",
      "__v": 3,
      "url": "",
      "tours": [
        {
           "_id": "53a47963ebe91d8a4a26d250",
           "title": "my test tour title",
           "url": "url_to_audio_file"
        }
      ],
      "images": []
    }
  ]
}

有谁知道这是否可能?任何帮助,将不胜感激!谢谢!

4

2 回答 2

0

@dylants 提供的解决方案是绝对正确的。但是,要使其正常工作,您需要在列表中tours声明为一个Types.Relationship字段,并将选项设置为.LocationrefTour

查看关于关系字段的 Keystone 文档。

我在下面的示例中包含了many:true选项,因为我认为这是一对多的关系。如果不是,您可以丢弃它。

var keystone = require('keystone'),
  Location = keystone.list('Location');

Location.add({
   ...
   tours: { type: Types.Relationship, ref: 'Tour', many: true },
   ...
});

您提到的List.relationship()方法仅适用于您希望相关文档列表自动出现在 中Keystone Admin UI,而不是建立实际关系。

希望这可以帮助。

于 2014-07-30T03:19:09.893 回答
0

看起来您已经将Location模型设置为对Tours 的引用,定义为 s 数组Tour。这意味着当您在您的Tour中存储 时Location,您不会存储表示该 的数据,Tour而是存储一个引用 的 ID Tour。当您执行该find操作时,您会在发回给客户端的响应中看到这一点。

如果是这种情况,那么您可能想看看Mongoose 的populate功能。这将获取这些引用并用它们包含的数据完全填充它们。

因此,例如,您可以将查询更改为以下内容:

Location.model.find().populate('tours').exec(function(err, items) {
    // items should now contain fully populated tours
}

如果这不是您的意思,请告诉我,我可以尝试进一步提供帮助。

于 2014-06-21T01:50:26.900 回答