Home > database >  How to use a document field from a stage in pipeline as reference to other pipeline in aggregation m
How to use a document field from a stage in pipeline as reference to other pipeline in aggregation m

Time:11-18

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

  • Related