0

How do I find an element in Meteor.user() and return other element in that same array in mongodb with meteor. How do I find course_id and get classes_id array?

this is in meteor.user

{
  "_id": "RoFFcaAfXBeR2napZ",
  "emails": [
    {
      "address": "tong@gmail.com",
      "verified": false
    }
  ],
  "classes": [
      {
         "course_id": "svesvinfdsgrvnekuktndvsk",
         "classes_id": ["myclass1", "myclass2"]
      },
      {
         "course_id": "cegtrtcrtvw5cgekrgecec",
         "classes_id": ["myclass3", "myclass4"]
      },
      {
         "course_id": "rvxwefdsrvyjvyccrhnkik",
         "classes_id": ["myclass5", "myclass6"]
      },
  ],
  "courses": [
    "qwmZdgQbrZ3rmHdN8"
  ]
}
phongyewtong
  • 3,925
  • 11
  • 38
  • 54
  • What is the expected result ? what have you tried ? – Thai Tran Feb 22 '16 at 10:36
  • Possible duplicate of [Retrieve only the queried element in an object array in MongoDB collection](http://stackoverflow.com/questions/3985214/retrieve-only-the-queried-element-in-an-object-array-in-mongodb-collection) – Blakes Seven Feb 22 '16 at 10:40
  • i tried this Meteor.user().classes.findOne({ course_id: this.props.courseId }) but i have "is not a function error" – phongyewtong Feb 22 '16 at 10:41
  • @BlakesSeven, I agree that it may seem like a duplicate, but since Meteor has a client-side implementation of a subset of MongoDB, the same result on the client cannot be achieved by using the same technique. – MasterAM Feb 22 '16 at 11:02
  • @MasterAM Nope. It's a duplicate. If there are not the standard projection operations available ( and yes they are for minimongo ), then the other case is using array filtering with aggregate methods on the "server side". The "meteor is different" is not an excuse. It's the same basic question that will always have the same basic answers. The only other "stupid" other cases are basically *"return all the array and filter it in your client code"*, which is not desirable when using a database. Still has the MongoDB, still applies. – Blakes Seven Feb 22 '16 at 11:08

2 Answers2

2

You can do it on the server using the Mongo's $ projection operator, but you cannot get the same functionality using MiniMongo out of the box, as it does not support this operator.

Let courseId hold the desired course id.

On the server, using:

c.find({"classes.course_id": courseId},{fields:{"courses.$": 1}})

should yield the desired result.

You will have to refactor your collection or use other tricks in order to get the same result on the client side.

One trick that comes to mind is using a mapping to leave only the desired courses:

function getClasses(courseId){
  return myCollection.find({"classes.course_id": courseId}).map((student) => {
    student.classes = _.filter(student.classes, (el) => el.course_id === courseId)
    return student;
  });
}

which also keeps your query reactive.

MasterAM
  • 15,074
  • 6
  • 40
  • 62
0

By default Meteor subscribes only the _id and profile object to the client. so you'll not be able to fetch your class records. you need to make a custom publish which returns your desired records and subscribe to that publication.

Faysal Ahmed
  • 1,494
  • 13
  • 23