-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Description
Do you want to request a feature or report a bug?
I think it's a bug with perDocumentLimit.
What is the current behavior?
Have 2 objects of the same Model M with each an array M.arr; both arrays have an entry that ref the same object X.
When populating with perDocumentLimit, I get, instead of just the populated X object, an array [X, X] within M.arr
If the current behavior is a bug, please provide the steps to reproduce.
This is the 9175.js with an added commonComment that is added to both Posts.
The script runs perfectly well without perDocumentLimit.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const assert = require('assert');
async function createFirstPost(Post, Comment, commonComment) {
const post = new Post({ title: 'I have 3 comments' });
const comment1 = new Comment({ content: 'Cool first post' });
const comment2 = new Comment({ content: 'Very cool first post' });
const comment3 = new Comment({ content: 'Super cool first post' });
post.commentsIds = [commonComment, comment1, comment2, comment3].map((comment) => comment._id);
await Promise.all([
post.save(),
comment1.save(),
comment2.save(),
comment3.save(),
]);
}
async function createSecondPost(Post, Comment, commonComment) {
const post = new Post({ title: 'I have 4 comments' });
const comment1 = new Comment({ content: 'Cool second post' });
const comment2 = new Comment({ content: 'Very cool second post' });
const comment3 = new Comment({ content: 'Super cool second post' });
const comment4 = new Comment({ content: 'Absolutely cool second post' });
post.commentsIds = [commonComment, comment1, comment2, comment3, comment4].map((comment) => comment._id);
await Promise.all([
post.save(),
comment1.save(),
comment2.save(),
comment3.save(),
comment4.save(),
]);
}
async function run() {
await mongoose.connect('mongodb://localhost:27017/test', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
await mongoose.connection.dropDatabase();
const postSchema = new Schema({
title: String,
commentsIds: [{ type: Schema.ObjectId, ref: 'Comment' }],
});
const Post = mongoose.model('Post', postSchema);
const commentSchema = new Schema({ content: String });
const Comment = mongoose.model('Comment', commentSchema);
const commonComment = new Comment({ content: 'Im used in two posts' });
await commonComment.save();
await createFirstPost(Post, Comment, commonComment);
await createSecondPost(Post, Comment, commonComment);
const posts = await Post.find().populate({ path: 'commentsIds', perDocumentLimit: 2 });
console.log(JSON.stringify(posts[0]));
// first comment should not be an array but is [commonComment, commonComment]
assert.notEqual(posts[0].commentsIds[0].length, 2);
assert.equal(posts[0].commentsIds.length, 2);
assert.equal(posts[1].commentsIds.length, 2);
console.log('All assertions passed.');
}
run().catch(console.error);This produces
{
"commentsIds":
[
[**
{"_id":"6021493f067381d74303df02","content":"Im used in two posts","__v":0},**
{"_id":"6021493f067381d74303df02","content":"Im used in two posts","__v":0}**
]**,
{"_id":"6021493f067381d74303df04","content":"Cool first post","__v":0}
],
"_id":"6021493f067381d74303df03","title":"I have 3 comments","__v":0
}What is the expected behavior?
It should include the commonComment only once and not an array of two commonComments.
What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
Node: v14.15.1
Mongoose: 5.11.15
MongoDB: v4.2.5