问题
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