admin管理员组

文章数量:1424079

I have two models: User and Track. User can plete and get points for every Track.

User schema:

let userSchema = new mongoose.Schema({
    name: {type: String, required: true},
    pletedTracks: [{
        type: mongoose.Schema.ObjectId,
        ref: 'Track',
    }],
});

Track schema:

let trackSchema = new mongoose.Schema({
  points: {
    type: Number,
    default: 0,
  }
});

I am storing references to pleted tracks in User model.

What I want to do is to query for multiple users, display only _ids of tracks pleted by each of them and add information about total points scored within a new score property.

Example of a result I would like to achieve:

[
    {
        "pletedTracks": [
            "5a9f14f18e04b3225953954c",
            "5aa5a8fa7367661c03f57a99",
            "5aa1aa5a7da9fd2946b01c04"
        ],
        "name": "Person 1",
        "score": 42,
        "id": "5aaab2c63d1a9d182b183a01"
    },
    {
        "pletedTracks": [],
        "name": "Person 2",
        "score": 0,
        "id": "5aaab602c5bdc411d3cef3bd"
    }
]

I tried to create virtual that would return the score but it does not work as userpletedTracks are just ObjectIds

userSchema.virtual('score').get(function() {
    return thispletedTracks.reduce((acc, doc) => acc + doc.points, 0);
});

I have two models: User and Track. User can plete and get points for every Track.

User schema:

let userSchema = new mongoose.Schema({
    name: {type: String, required: true},
    pletedTracks: [{
        type: mongoose.Schema.ObjectId,
        ref: 'Track',
    }],
});

Track schema:

let trackSchema = new mongoose.Schema({
  points: {
    type: Number,
    default: 0,
  }
});

I am storing references to pleted tracks in User model.

What I want to do is to query for multiple users, display only _ids of tracks pleted by each of them and add information about total points scored within a new score property.

Example of a result I would like to achieve:

[
    {
        "pletedTracks": [
            "5a9f14f18e04b3225953954c",
            "5aa5a8fa7367661c03f57a99",
            "5aa1aa5a7da9fd2946b01c04"
        ],
        "name": "Person 1",
        "score": 42,
        "id": "5aaab2c63d1a9d182b183a01"
    },
    {
        "pletedTracks": [],
        "name": "Person 2",
        "score": 0,
        "id": "5aaab602c5bdc411d3cef3bd"
    }
]

I tried to create virtual that would return the score but it does not work as user.pletedTracks are just ObjectIds

userSchema.virtual('score').get(function() {
    return this.pletedTracks.reduce((acc, doc) => acc + doc.points, 0);
});
Share Improve this question edited Mar 16, 2018 at 21:21 umat asked Mar 16, 2018 at 21:08 umatumat 7252 gold badges13 silver badges27 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

You can try below aggregation in 3.4.

$lookup to look up the points for pleted tracks followed by $addFields to return a score field summing the points and $project with exclusion to drop the lookup-data field from response.

UserModel.aggregate([
  {"$lookup":{
    "from":"tracks", // name of the foreign collection
    "localField":"pletedTracks",
    "foreignField":"_id",
    "as":"lookup-data"
  }},
  {"$addFields":{
    "score":{
      "$sum":"$lookup-data.points"
    }
  }},
  {"$project":{"lookup-data":0}}
])

本文标签: javascriptMongoose sum fields from populated documentsStack Overflow