skip to Main Content

I have my data structured like this that I get from localhost:3000/api/notes/[noteTitle]/note2

{
  "data": [
      {
          "_id": "62ff418fa4adfb3a957a2847",
          "title": "first-note2",
          "note": { "_id": "62ff399da4adfb3a957a2808", "title": "first" },
      },
      {
          "_id": "631af43b054a6aef1a7c4f08",
          "title": "first-note22",
          "note": { "_id": "62ff399da4adfb3a957a2808", "title": "first" },
      },
      {
          "_id": "631af504054a6aef1a7c4f11",
          "title": "second-note22",
          "note": { "_id": "62ff3a10a4adfb3a957a2817", "title": "second" },
      }
  ]
}

When I send an API request to localhost:3000/api/notes/first/note2 I want to fetch only those data that have the title "first" in the note object.

I tried doing it like this in the API pages:

export default async (req, res) => {
  const { query: { noteTitle }, method } = req;

  switch (method) {
    case "GET":
      try {
        const notes = await Note2.find({"note.title": noteTitle}).populate("note");
        res.status(200).json({ success: true, data: notes });
      } catch (error) {
        console.log(error);
      }
      break;

    default:
      res.status(400).json({ success: false });
      break;
  }
};

But it returns an entry array even though I should get two matches.

Where did I go wrong?

Edit: This is how my Note2 schema looks:

const Note2Schema = new mongoose.Schema({
  title: { type: String, unique: true },
  note: { type: mongoose.Schema.Types.ObjectId, ref: "Note" },
});
module.exports = mongoose.models.Note2 || mongoose.model("Note2", Note2Schema);

And my Note Schema:

const NoteSchema = new mongoose.Schema({
  title: { type: String, unique: true }
});
module.exports = mongoose.models.Note || mongoose.model("Note", NoteSchema);

Edit 2: I found this in the mongoose docs. Seems like I can’t find any data that I’m populating and using that populated data in the find method.

Is there any workaround solution for what I want to achieve?

In general, there is no way to make populate() filter stories based on properties of the story's author. For example, the below query won't return any results, even though author is populated.

const story = await Story.
  findOne({ 'author.name': 'Ian Fleming' }).
  populate('author').
  exec();
story; // null

2

Answers


  1. Chosen as BEST ANSWER

    As I found in the mongoose docs, there is no way to make populate() filter notes based on the properties of the note2's title.

    const notes = await Note2.find({ })
      .populate({
        path: 'note',
        match: { title: noteTitle },
      })
      .exec();
    

    And my goal was to get only the two data that have the "first" string on the note.title in it. So I found a workaround solution using a second filter after I get all the Note2 data from the database.

    const notes = await Note2.find({}).populate({ path: "note" })
    
    const selectedNote2 = notes.map((singleNote) => {
      if (singleNote.note.title === noteTitle) {
        return singleNote
      }
      return []
    })
    
    res.status(200).json({ success: true, data: selectedNote2});
    

    I don't know if there's a better solution than this one.


  2. "note" is an object property which is inside of the array named "data". So your query should be like this –

    const notes = await Note2.find({"data.note.title": noteTitle}).populate("note");
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search