1

我试图在我的 REST 服务器的 GET 输出中隐藏某些字段。我有 2 个模式,都有一个字段将彼此的相关数据嵌入到 GET 中,因此获取 /people 将返回他们工作的位置列表,并获取位置列表返回在那里工作的位置。但是,这样做会添加一个 person.locations.employees 字段,然后会再次列出员工,这显然是我不想要的。那么如何在显示之前从输出中删除该字段呢?谢谢大家,如果您需要更多信息,请告诉我。

/********************
/ GET :endpoint
********************/
app.get('/:endpoint', function (req, res) {
    var endpoint = req.params.endpoint;

    // Select model based on endpoint, otherwise throw err
    if( endpoint == 'people' ){
        model = PeopleModel.find().populate('locations');
    } else if( endpoint == 'locations' ){
        model = LocationsModel.find().populate('employees');
    } else {
        return res.send(404, { erorr: "That resource doesn't exist" });
    }

    // Display the results
    return model.exec(function (err, obj) {
        if (!err) {
            return res.send(obj);
        } else {
            return res.send(err);
        }           
    });   
});

这是我的 GET 逻辑。所以我一直在尝试在填充函数之后使用猫鼬中的查询函数来尝试过滤掉这些引用。这是我的两个架构。

peopleSchema.js

return new Schema({
    first_name: String,
    last_name: String,
    address: {},
    image: String, 
    job_title: String,
    created_at: { type: Date, default: Date.now },
    active_until: { type: Date, default: null },
    hourly_wage: Number,
    locations: [{ type: Schema.ObjectId, ref: 'Locations' }],
    employee_number: Number
}, { collection: 'people' });

locationSchema.js

return new Schema({
    title: String,
    address: {},
    current_manager: String, // Inherit person details
    alternate_contact: String, // Inherit person details
    hours: {},
    employees: [{ type: Schema.ObjectId, ref: 'People' }], // mixin employees that work at this location
    created_at: { type: Date, default: Date.now },
    active_until: { type: Date, default: null }
}, { collection: 'locations' });
4

4 回答 4

3

您应该使用 select() 方法指定要获取的字段。您可以通过执行以下操作来做到这一点:

if( endpoint == 'people' ){
        model = PeopleModel.find().select('locations').populate('locations');
    } else if( endpoint == 'locations' ){
        model = LocationsModel.find().select('employees').populate('employees');
    } // ...

您可以通过用空格分隔来选择更多字段,例如:

PeopleModel.find().select('first_name last_name locations') ...
于 2013-09-23T00:40:10.383 回答
1

Select 是正确的答案,但它也可能有助于在您的架构中指定它,以便您保持 API 的一致性,我发现它有助于我不记得在对对象执行查询的任何地方都这样做。

您可以使用select: true|false架构字段上的属性将架构中的某些字段设置为永不返回。

更多细节可以在这里找到:http: //mongoosejs.com/docs/api.html#schematype_SchemaType-select

于 2015-11-13T01:21:17.383 回答
0

解决方案!

因为这对我来说很难找到,所以我要把它留给其他人。为了“取消选择”填充的项目,只需在您的选择中为该字段添加“-”前缀。例子:

PeopleModel.find().populate({path: 'locations', select: '-employees'});

现在locations.employee's 将被隐藏。

于 2013-09-23T00:45:13.230 回答
0

如果您还记得 SQL 时代,SELECT 会对正在查询的表进行限制。Restrict 是关系模型的基本操作之一,随着关系模型的发展,它仍然是一个有用的特性。等等等等等等。

在 mongoose 中,Query.select() 方法允许您使用一些额外的功能来执行此操作。特别是,您不仅可以指定要返回的属性(列),还可以指定要排除的属性。

所以这里是例子:

function getPeople(req,res, next) {
   var query = PeopleModel.find().populate({path: 'locations', select: '-employees'});

   query.exec(function(err, people) {
      // error handling stuff
      // process and return response stuff 
   });
}

function getLocations(req,res, next) {
   var query = LocationModel.find().populate({path: 'employees', select: '-locations'});

   query.exec(function(err, people) {
      // error handling stuff
      // processing and returning response stuff 
   });
}

app.get('people', getPeople);
app.get('locations', getLocations);

直接来自猫鼬文档:

转到http://mongoosejs.com/docs/populate.html并搜索“查询条件和其他选项”

查询条件和其他选项

如果我们想根据他们的年龄填充我们的粉丝数组,只选择他们的名字,并且最多返回任意 5 个呢?

Story
.find(...)
.populate({
  path: 'fans',
  match: { age: { $gte: 21 }},
  select: 'name -_id',
  options: { limit: 5 }
})
.exec()

我只是想说明一下,为了端点的简单性,您可以用这种方式来定义端点。但是,一般来说,这种调度器模式不是必需的,并且在使用 Express 开发时可能会在以后的开发中造成问题。

于 2014-03-19T17:08:06.540 回答