how can I rewrite my mongoose query after splitting data from one model into two?

元气小坏坏 提交于 2019-11-30 20:31:08

问题


In my application I store comments. Previously my model for that looked like this:

var CommentsSchema = new Schema({
    username: {type: String},
    display_name: {type: String},
    facebook_username: {type: String},
    text_content: {type: String},
    photo_content_url: {type: String},
    hashtags: {type: [String]},
    device_id: {type: String},
    comment_date: {type: Date, default: Date.now},
    friends_only: {type: Boolean, default: false}
}

Each comment - besides storing its details - had also details about the author, e.g. username, facebook_username, device_id from which the comment was added and display_name. There was also a bool flag friends_only based on which I was deciding whether that comment should be visible only to user's facebook friends or to everyone.

Construction of the node.js/mongoose query for fetching all comments looked like this:

commentsRoutes.post('/friends', function (req, res) {
    var friends = req.body.friends;
    var publicComments = req.body.publicComments;

    var hashtagsInput = req.body.hashtags;

    var startDate = req.body.startDate;
    var endDate = req.body.endDate;

    var query= {};
    query.$and = [];

    // and condition on start date
    if(startDate != undefined) {
        var startDate = new Date(req.param('startDate'));
        var endDate = new Date(req.param('endDate'));
        query.$and.push({"comment_date":{$gte: startDate}});
        query.$and.push({"comment_date":{$lte: endDate}});
    }

    // and condition on hastags
    if (hashtagsInput != undefined) {
        var hashtags = hashtagsInput.split(",");
        query.$and.push({"hashtags":{$in: hashtags}});
    }

    // creating a OR condition for facebook friends and public flag
    var friend_query = {};
    friend_query.$or = [];

    if (friends != undefined) {
        var friendsSplit = friends.split(",");
        friend_query.$or.push({"facebook_username":{$in: friendsSplit}});
    }

    if (publicComments != undefined && publicComments === "true") {
        friend_query.$or.push({friends_only: false});
    }

    //Merging facebook friend condition with other condition with AND operator.
    query.$and.push(friend_query);

    var finalQuery = Comment.find(query)

With the code above user could fetch content posted by his friends (that was set either to public or private) and all other public content (from everyone else).

I've decided to change all of that and split the data into two models. After changing it I have:

var CommentsSchema = new Schema({
    user_id: {type: String, required: true, ref: 'users' },
    text_content: {type: String},
    photo_content_url: {type: String},
    hashtags: {type: [String]},
    comment_date: {type: Date, default: Date.now},
    friends_only: {type: Boolean, default: false},
    device_id: {type: String}
}

and

var UsersSchema = new Schema({
    username: {type: String},
    facebook_username: {type: String},
    display_name: {type: String}
}

Now, when I want to keep the old functionality, I need to modify the code responsible for creating the query. I could merge two queries with async, or the other way is to use mongoose .populate option. I decided to go with the second choice, so now I need to move the code responsible for creating or query to the match part of populate function:

...
var finalQuery = Comment.find(query)

finalQuery.populate({path: 'user_id', 
    select: 'facebook_username display_name username',
    match: {

}});

I don't know how to do it. Can you help me with that?


回答1:


First, i suggest you that go with a populate query, if you feel that populate won't give you a data that you need that you can run two queries and merge those results.

for populate, i found the solution from the official doc of mongoose. you can do like this.

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

var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
  fans     : [{ type: Number, ref: 'Person' }]
});

var Story  = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);

Story
.findOne({ title: 'Once upon a timex.' })
.populate('_creator')
.exec(function (err, story) {
  if (err) return handleError(err);
  console.log('The creator is %s', story._creator.name);
  // prints "The creator is Aaron"
});

here is doc link: http://mongoosejs.com/docs/populate.html



来源:https://stackoverflow.com/questions/41212600/how-can-i-rewrite-my-mongoose-query-after-splitting-data-from-one-model-into-two

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!