0

I know that there are similar questions to this one, but the answers to those have not yielded the correct result.

I want to query a nested object with mongoose find. This is what I currently have setup:

reportRoutes.route('/:id').get(async (req, res) => {
    try{
        let id = req.params.id
        let author = req.params.author
        let regex = new RegExp( id, 'i')
        const report = await Report.find({title: regex, 'player.player_name':  "James Harden" })
            .populate({path: 'like'})
            .populate({
                path: 'player',
                populate: [{ path: 'team' },
                {
                    path: 'team',
                    populate: {
                        path: 'league'
                    }
                }
            ]
            })
            res.json(report)
    }  catch (e) {
        res.status(500).send()
    }
})

When I run this in postman, I receive a blank array.

This is the route that query string that I'm using: localhost:4000/reports/harden

This is the schema for Report:

const mongoose = require('mongoose')
const Schema = mongoose.Schema

let Report = new Schema({
    title: {
        type: String
    },
    summary: {
        type: String
    },
    analysis: {
        type: String
    },
    source_title: {
        type: String
    },
    source_link: {
        type: String
    },
    author: {
        type: String
    },
    like: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Like'
    }],
    player: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref: 'Player'
    }
}, { timestamps: true })

module.exports = mongoose.model('Report', Report)

And this is the schema for player:

const mongoose = require('mongoose')
const Schema = mongoose.Schema

let Player = new Schema({
    player_name: {
        type: String
    },
    player_position: {
        type: String
    },
    team: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref: 'Team'
    }
}, { timestamps: true })

module.exports = mongoose.model('Player', Player)
schoenbl
  • 663
  • 2
  • 14
  • 29
  • What happens when you search for just `title` without the nested player etc. Do you get any results then? Search with no regEx and for title only and see if all the populates worked. Also try removing all the `populate`s and see if you get results with the regEx etc. – Akrion May 26 '19 at 04:37
  • @akrion when i search for `title` with regex, I receive the correct result, and all of the populates work. no regEx, I receive an empty array. Tried to remove populates with the regex, and received an empty array. Whenever I receive an empty array, postman tells me that I have a `200 OK`. Thanks for the help, I'm pretty stuck on this one. – schoenbl May 26 '19 at 04:53

1 Answers1

1

Since you are using populate try using the match stage:

reportRoutes.route('/:id').get(async (req, res) => {
    try{
        let id = req.params.id
        let author = req.params.author
        let regex = new RegExp( id, 'i')
        const report = await Report.find({ title: regex })
        .populate({path: 'like'})
        .populate({
           path: 'player',
           match: { 'player_name': 'James Harden'},  // <-- match here
           populate: [{ path: 'team' },
           {
             path: 'team',
             populate: {
             path: 'league'
           }
         }]
        })
        res.json(report)
    }  catch (e) {
        res.status(500).send()
    }
})

Documentation on this can be found here

Akrion
  • 18,117
  • 1
  • 34
  • 54
  • thanks, this works. Any idea why the dot notation does not work? – schoenbl May 26 '19 at 07:12
  • You can't query at the top level down like that since the data is not yet `populated`. This is why the match stage is there. – Akrion May 26 '19 at 07:13
  • I looked a little closer, and this actually does not work. It is picking up the initial find, but then ignores the match on the player name. – schoenbl May 26 '19 at 15:22