These are chat archives for Automattic/mongoose

28th
Nov 2017
scare4face
@scare4face
Nov 28 2017 16:39 UTC
@joeytwiddle wow thanks for the tip
scare4face
@scare4face
Nov 28 2017 16:44 UTC
i have a form with four inputs with data to be rendered to the view. how do i collect the data from the form on submit by just using express. any help? kinda new to forms tho

i have the following structure in my document…

{
  _id: ‘abcd1234’,
  episodes: [ { eId: ‘e1234’ }, { eId: ‘e4567’ } ]
}

not sure if i am doing this correctly, but the following returns the entire episodes array, with both e1234 and e4567 in the result

User.find({ _id: ‘abcd1234’ })
  .where(‘episodes.eId’).equals(‘e1234’)
  .exec()

any ideas?

Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:27 UTC
@goto1 you need elementMatch
i did elementMatch, what I am looking for is filtering capabilities… this obviously is not the filtering but rather returning ALL documents that match the query
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:29 UTC
you need to project only one object from array :)
i had to read the docs 10x before fully understanding what it actually does lol
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:29 UTC
projection -> elemMatch :)
it is quite easy
there might be multiple objects with the eId equal to e1234
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:30 UTC
it should match them all
it matches all docs that match the query
but the resulting array will consist of all items in the array for that doc
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:30 UTC
not if you use elemMatch in projection :)
so then i have to do doc.array.filter(item => item.eId === eId) type of thing
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:31 UTC
consider this
but that will only return a single item, i will need multiple ones, that could potentially have the attribute of eId equal to e1234

this is possible

[ { eId: ‘1234’ }, { eId: ‘1234’ }, { eId: ‘4567’ } ]

eId is neither the primary key nor unique

Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:32 UTC

User.find({ _id: ‘abcd1234’ }, { episodes: { $elemMatch: { eId: 1234  } } })
  .exec()
let me test this
that only returns the first item
it says in the docs
The $elemMatch operator limits the contents of an <array> field from the query results to contain only the first element matching the $elemMatch condition.
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:33 UTC
yes you are right
there was change regarding that as well
yeah its some crazy thing i need to do to accomplish what i want to do, so its prob easier to just do it programmatically
which is the solution i opted in for, thanks anyway!
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:36 UTC
sec
i m curious now
this is kind of what I wanted to accomplish, as per the answer on this thread
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:39 UTC
can you use aggregation ?
i am not entirely sure what aggregation does in mongoose, its hard to follow these docs sometimes lol
as per the docs…
Mongoose#Aggregate()

The Mongoose Aggregate constructor
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:43 UTC
db.notes.aggregate(
    // Pipeline
    [
        // Stage 1
        {
            $match: {
            _id: ObjectId("5a1bdb6a632c90001ece96fe")
            }
        },

        // Stage 2
        {
            $project: {
                history: {
                        $filter: {
                           input: "$history",
                           as: "item",
                           cond: { $eq: [ "$$item.title", "ut volutpat sapien" ] }
                        }
                     },
               title: 1,
            }
        },
    ]
);
i tested this now in 3T studio ... and it works
where my history is your episodes
and it iterates trough each element and execute $eq operator
right, so it will return multiple history sub-docs, right? all with the title of ut volutpat sapien… correct?
in case i remove last $filter pipe
i have 3 objects thre
cool, thanks a lot! i will definitely try this out
much appreciated!
i wonder about the performance difference between this and doing it programmatically
its prob better to just delegate this type of work to mongodb though
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:50 UTC
User.aggregate([
 {
   $match : {
    _id: 'abcd1234'
   }
 },
 $filter: {
  episodes: {
            $filter: {
               input: "$episodes",
               as: "item",
               cond: { $eq: [ "$$item.eId", 1234 ] }
            }
         },
   title: 1,
}
])
something like this :) @goto1
if data set is huge... than better candidate is Aggregation
thanks a lot! reading the docs on mongodb on aggregation to better understand this trick then will try it out
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:50 UTC
if it is not huge, it does not matter
yeah, it might get large, so i will prob switch to aggregation
thanks, i appreciate the help!
Vlado Tesanovic
@vladotesanovic
Nov 28 2017 22:52 UTC
nothing,
hopes everything will work
i am sure this will do the trick, thanks :clap: