book model is:
const BookSchema = new Schema(
{
title: { type: String, required: true },
author_id: { type: Schema.Types.ObjectId, ref: 'User' },
summary: { type: String, required: true },
isbn: { type: String },
genre: [{ type: String, required: true }],
doc: {},
img: { type: String },
review_id: [{ type: Schema.Types.ObjectId, ref: 'Review' }],
pub_date: { type: Date, required: true },
totalRating: { type: Number, default: 0},
ratingCount: { type: Number, default: 0 },
hotRank: { type: Number, default: 0 },
popRank: { type: Number, default: 0 }
}
);
Now, I am trying to make a mongodb query which finds book by it's id and in same query finds its similar counterparts by genre tags comparison something like:
db.books.aggregate(
[
{ $match: { _id: `book_id` } }, {
$addFields: {
"count": {
$size: {
$setIntersection: ["$genre", `founded_book_genre_tag`]
}
}
}
}, {
$sort: {
"count": -1
}
}, {
$project: { _id: 1, title: 1 }
}
])
Note: Tag matching part works I just want to find out on how to use reference of a field from one stage of pipeline to other.
Edit:
consider documents:
[
{
"_id": 1,"title": "sample1","genre": ["Sports","War","Fantasy"]
},
{
"_id": 2,"title": "sample2","genre": ["Fantasy","Games","War"]
},
{
"_id": 3,"title": "sample3","genre": ["Fantasy","Games","Sports","War"]
},
{
"_id": 4, "title": "sample4","genre": ["Games", "Fantasy","War","Action","Urban"]
},
{
"_id": 5, "title": "sample5","genre": ["History","Fantasy","Mystery","War"]
}
]
So, if I search for document with id 2 then I should recommendation of book with id 3 & 4
Output if book searched with id 2 should be something like this:
{
_id: 2,
title: "sample2",
genre: ["Fantasy","Games","War"],
recd: [
{_id:3}, {_id: 4}
]
}
CodePudding user response:
One option is:
db.collection.aggregate([
{$match: {_id: 2}},
{$lookup: {
from: "collection",
let: {genre: "$genre"},
pipeline: [
{$match: {$expr: {$eq: [{$setIsSubset: ["$$genre", "$genre"]}, true]}}},
{$project: {_id: 1}},
{$match: {_id: {$ne: 2}}}
],
as: "recd"
}
}
])
See how it works on the playground example