将嵌入的文档隐藏在mongoose / node REST服务器中

时间:2013-09-23 00:28:02

标签: node.js express mongoose

我正在尝试隐藏我的REST服务器的GET输出上的某些字段。我有两个模式,都有一个字段可以将相关数据从彼此嵌入到GET中,因此获取/人员将返回他们工作的位置列表,并获取位置列表返回谁在那里工作。但是,这样做会添加一个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逻辑。所以我一直试图在populate函数之后使用mongoose中的查询函数来尝试过滤掉那些引用。这是我的两个架构。

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

locationsSchema.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 个答案:

答案 0 :(得分: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') ...

答案 1 :(得分:1)

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

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

可在此处找到更多详细信息:http://mongoosejs.com/docs/api.html#schematype_SchemaType-select

答案 2 :(得分:0)

解!

因为这对我来说很难发现我会把这个留给其他人。要“取消选择”已填充的项目,只需在选择中使用“ - ”作为字段的前缀。例如:

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

现在locations.employee将被隐藏。

答案 3 :(得分:0)

如果您记得SQL日期,SELECT会对要查询的表执行限制。限制是关系模型中的原始操作之一,并且随着关系模型的发展,它仍然是一个有用的特性。等等等等。

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

直接来自Mongoose Docs:

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

  

查询条件和其他选项

     

如果我们想根据他们的年龄填充我们的粉丝阵列怎么办?   只选择他们的名字,最多返回其中任何5个?

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

我只是想说,为了简化端点,您可以通过这种方式来定义端点。但是,通常这种调度程序模式不是必需的,并且在使用Express进行开发时可能会在开发后期出现问题。