2015-07-05 1 views
2

Я новичок в mongoose и узле, и я создаю приложение, используя стек MEAN (Mongo ExpressJS AngularJS Node).Создайте Mongoose DTO для приложения MEAN

В прошлом я создал много API, используя asp.net WebAPI, и я не могу найти никакой документации по использованию DTO или View Models, чтобы уменьшить объем JSON, переданный туда и обратно между мой сервер и мой интерфейс.

Мое приложение относится к опросу, который пользователи заполняют онлайн. Каждый ответ затем используется для создания оценки пользователем.

Мои модели:

var UserSchema = new Schema({ 
    email: {type: String, trim: true,default: '', match: [/.+\@.+\..+/,'']}, 
    status: {type: String}, 
    token:{type: String, default: crypto.randomBytes(64).toString('hex')}, 
    score: { 
     managementExperience: {type: Number}, 
     managementSkills: {type: Number}, 
     relevantKnowledge: {type: Number}, 
     commitment: {type: Number}, 
     acceptanceOfChange: {type: Number}, 
     age: {type: Number}, 
     totalScore: {type: Number} 
    }, 
    answers: [ 
     { 
      optionId: {type: Schema.Types.ObjectId} 
     } 
    ] 
}); 

var SurveySchema = new Schema({ 
    client_id:{type: Schema.Types.ObjectId, ref: 'Client' }, 
    creationDate:{type: Date,default: Date.now}, 
    title: {type: String, trim: true}, 
    surveyVersion: { type: Schema.Types.ObjectId, ref: 'SurveyVersion' }, 
    users:[UserSchema] 
}); 

Сам экран изыскательные работы, но когда дело доходит до получения приборной панели результатов, я хотел бы послать DTO и не весь SurveySchema, как эта модель:

В .Net мире У меня была бы эта модель, у которой был бы конструктор, который принимает в качестве параметров экземпляр SurveySchema, но я не могу найти способ заставить его работать.

Я также попытался оба Schemas связаны с одной и той же коллекции в MongoDB:

mongoose.model('Survey', SurveySchema); 
mongoose.model('SurveyLight', SurveySchemaLight, 'surveys'); 

Но когда я запускаю следующий запрос на SurveyLight схеме, я до сих пор есть все поля из обзора вернулся:

SurveyLight.find({'client_id': req.params.clientID}).exec(function(err, surveyList){ 
     res.json(surveyList); 
    }); 

Что было бы лучше всего использовать механизм DTO/View Model в моем стеке?

Благодаря

ответ

3

Для запросов «mongoose» и MongoDB в целом вы просто «проецируете» нужные вам поля в своем представлении, игнорируя других, которых вы не хотите.

Как автономный пример:

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

var childSchema = new Schema({ 
    "longName": String, 
    "email": String, 
    "status": String 
}) 

var parentSchema = new Schema({ 
    "name": String, 
    "longDescription": String, 
    "children": [childSchema] 
}) 

mongoose.connect('mongodb://localhost/test'); 

var Parent = mongoose.model('Parent', parentSchema); 

async.waterfall(
    [ 
    // remove any samples 
    function(callback) { 
     Parent.remove({},function(err,res) { 
     callback(err) 
     }); 
    }, 

    // insert some test data 
    function(callback) { 
     Parent.create(
     { 
      "name": "Bill", 
      "longDescription": "Something we don't want to see", 
      "children": [ 
      { "longName": "don't want", "email": "[email protected]", "status": "A" }, 
      { "longName": "don't want", "email": "[email protected]", "status": "B" } 
      ] 
     }, 
     function(err,doc) { 
      console.log(doc); 
      callback(err,doc); 
     } 
    ) 
    }, 

    // Fetch just the fields we want 
    function(doc,callback) { 
     Parent.find({},"name children.email children.status", callback); 
    } 
    ], 

    // Ouput results 
    function(err,result) { 
    if (err) throw err; 
    console.log(result); 
    process.exit(); 
    } 
); 

, который выводит в следующем виде:

// The original form of the documents 
{ __v: 0, 
    name: 'Bill', 
    longDescription: 'Something we don\'t want to see', 
    _id: 5598b6bad439a31807bfe746, 
    children: 
    [ { longName: 'don\'t want', 
     email: '[email protected]', 
     status: 'A', 
     _id: 5598b6bad439a31807bfe748 }, 
    { longName: 'don\'t want', 
     email: '[email protected]', 
     status: 'B', 
     _id: 5598b6bad439a31807bfe747 } ] } 

// The output document with just selected fields 
[ { _id: 5598b6bad439a31807bfe746, 
    name: 'Bill', 
    children: 
    [ { email: '[email protected]', status: 'A' }, 
     { email: '[email protected]', status: 'B' } ] } ] 

Если вы хотите, чтобы «исключить» поля, а не называть их всех явно то префикс - как в

"-longName -children.logDescription" 

Но вы не можете «смешивать» два термина, с t он исключение "-_id"

+0

Спасибо Блэйкс, я не знал этого синтаксиса, чтобы перечислить поля для вывода! –

1

В JavaScript мире, вы должны попытаться подойти к этой проблеме с точки зрения функционального программирования. У вас есть данные, вы хотите вернуть подмножество этих данных. Вам не требуется отдельное определение модели, вам просто нужна функция map/filter.

например.

SurveyLight.find({'client_id': req.params.clientID}).exec(function(err, surveyList){ 
     var parsedSurveyList = surveyList.map(function(survey){ 
      survey.users = survey.users.map(function(user){ 
      return {email: user.email, status: user.status}; 
      }); 
      return survey; 
     }); 
     res.json(parsedSurveyList); 
    }); 

Вы можете сделать это намного лучше с использованием популярных функциональных библиотек, таких как lodash.

+0

Спасибо, Юрий, я больше спрашивал, можно ли использовать механизм мангуста, чтобы избежать такого рода кода. –