0

I have a collection of fixtures, which contain nested arrays. I want to able to search robustly. Here is my model and my code below. Thank you

const team = {
  ref: 'TeamModel',
  type: Array,
  name: {
    type: String,
    enum: ['AFC Bournemouth', 'Arsenal', 'Aston Villa', 'Brighton & Hove Albion', 'Burnley', 'Chelsea',
      'Crystal Palace', 'Everton', 'Leicester City', 'Liverpool', 'Manchester City', 'Manchester United',
      'Newcastle United', ' Norwich City', 'Sheffield United', 'Southampton', 'Tottenham Hotspur', 'Watford',
      'West Ham United', 'Wolverhampton Wanderers']
  },
  score: { type: Number, default: 0 }
};

const fixtureSchema = mongoose.Schema({
  _id: mongoose.Schema.Types.ObjectId,
  teamA: team,
  teamB: team,
  status: { type: String, default: 'pending' },
  matchInfo: {
    type: Array,
    date: Date,
    stadium: {
      type: String,
      enum: ['Vitality Stadium', 'The Amex', 'Turf Moor', 'Cardiff City Stadium',
        "John Smith's Stadium", 'King Power Stadium', 'Goodison Park', 'Anfield',
        'Emirates Stadium', 'Stamford Bridge', 'Selhurst Park', 'Craven Cottage',
        'Wembley Stadium', 'London Stadium', 'Etihad Stadium', 'Old Trafford',
        'St James Park', "St Mary's Stadium", 'Vicarage Road', 'Molineux Stadium']
    }
  },
  createdAt: { type: Date, default: moment(Date.now()).format('LLLL') },
  updatedAt: { type: Date, default: moment(Date.now()).format('LLLL') },
});
    const {
      name, date, stadium, status, score
    } = req.body;
    try {
      if (name || date || stadium || status) {
        const fixture = await FixtureModel.find({
          $or: [
            { status },
            { teamA: { name, score } },
            { teamB: { name, score } },
            { matchInfo: { $elemMatch: { date, stadium } } },
          ]
        })
          .exec();
        if (fixture.length <= 0) {
          return response(res, 404, 'error', {
            message: messages.fixtureNotFound
          });
        }
        return response(res, 200, 'success', {
          fixture
        });
      }
    } catch (error) {
      console.log(error);
      return response(res, 400, 'error', {
        message: messages.error
      });
    }
  }

With my present implementation, only the search with status works. searching with others returns an empty object despite having match parameters in the collection.

status: can either be ['completed', 'pending'] stadium: can either be ['Vitality Stadium', 'The Amex', 'Turf Moor', 'Cardiff City Stadium', "John Smith's Stadium", 'King Power Stadium', 'Goodison Park', 'Anfield', 'Emirates Stadium', 'Stamford Bridge', 'Selhurst Park', 'Craven Cottage'...]

Here is the repo branch . the function is at line 297

  • Show an example. i.e what `date` and `stadium` values are you supplying to the query? Also show at least one example document you expect to match. A question of "Why is this not working?" actually requires you to provide enough information for others to reproduce. – Neil Lunn Sep 29 '19 at 07:22
  • When you say **either** do you mean your query is effectively `{ $elemMatch: { stadium: "Vitality Stadium" } }` or do you mean you actually did `{ $elemMatch: { stadium: ['Vitality Stadium', 'The Amex', 'Turf Moor', 'Cardiff City Stadium'] } }` or similar? If the **latter**, then the query condition is **incorrect**, and you mean `$elemMatch: { stadium: { "$in": ['Vitality Stadium', 'The Amex', 'Turf Moor', 'Cardiff City Stadium'] } } }` – Neil Lunn Sep 29 '19 at 07:46
  • To be clear, [`$in`](https://docs.mongodb.com/manual/reference/operator/query/in/) is basically an OR condition on the same field. Without it you are essentially looking for an **exact match** where a sub-document contains that **specific array** for that field. Which of course it does not, and therefore you get no result. – Neil Lunn Sep 29 '19 at 07:54

0 Answers0