Using $elemMatch with $gt to find the right content of the array and how to only return arrays matching that criteria

427 views
Skip to first unread message

Jonathan Thurft

unread,
Oct 16, 2013, 8:45:11 AM10/16/13
to mongod...@googlegroups.com
I am trying to find a X user whose delimiter is equal to  Y. That works find and I can retrieve the document.

Now... Inside that document I've an `Event field` of type `array` that contain other objects.
The user will request only the items of the array from their last timeStamp fetch. so I want just the ones whose `ts` is greater than `XX`

My current query always returns all the results. Is there a way to limit the returned results to the ones that are greater than `XX`??

I am not sure thats possible in mongo, but maybe there is a way?


**Query**
  

      public function testFindInarray() {
        $db = $this->db()->socialWall;
        
        $where = array( 'userId' =>  new MongoId("525c6be048fde2112e8b4626"), 
        'delimeter' =>  21013,
        'event' => array('$elemMatch' =>  array('ts' => array( '$gt' => new MongoDate(1381924477) ) ) )
         );
        
        return $db->find( $where );
        }

**Result dump**

    Array
    (
        [_id] => MongoId Object
            (
                [$id] => 525e7dd3f51e9e2d5e127b05
            )
    
        [delimeter] => 21013
        [event] => Array
            (
                [0] => Array
                    (
                        [_id] => MongoId Object
                            (
                                [$id] => 525e7de348fde2132e8b45f4
                            )
    
                        [userId] => MongoId Object
                            (
                                [$id] => 525c6be048fde2112e8b4626
                            )
    
                        [verb] => addedRoutine
                        [ts] => MongoDate Object
                            (
                                [sec] => 1381924323
                                [usec] => 757000
                            )
    
                        [details] => Array
                            (
                                [resourceID] => MongoId Object
                                    (
                                        [$id] => 525e7de348fde2132e8b45f3
                                    )
    
                                [resourceName] => testr
                                [authorName] => todk
                                [exerciseType] => Array
                                    (
                                        [0] => chest
                                    )
    
                            )
    
                        [likedBy] => Array
                            (
                            )
    
                        [comments] => Array
                            (
                            )
    
                    )
    
                [1] => Array
                    (

Rob Moore

unread,
Oct 16, 2013, 9:22:05 PM10/16/13
to mongod...@googlegroups.com

You want to use the "$elemMatch" projection operator to thin the array.


You pass the projection as the second field in the find() in the shell.  Your driver's documentation should tell you how to use one.  Look for "fields", or "projection" in the documentation.

Here is an example using the shell (note there was only one document on the collection so I trimmed the query to {}.

> db.test.findOne()
{
"_id" : ObjectId("525f3a7009af0bddba06991f"),
"events" : [
{
"f" : 1,
"date" : ISODate("2013-10-16T00:00:00Z")
},
{
"f" : 2,
"date" : ISODate("2013-10-15T00:00:00Z")
}
]
}
> db.test.find( {} , { "events" : { "$elemMatch" : { "date" : { "$gt" : ISODate("2013-10-15T00:00:00Z") } } } } )
{ "_id" : ObjectId("525f3a7009af0bddba06991f"), "events" : [  {  "f" : 1,  "date" : ISODate("2013-10-16T00:00:00Z") } ] }

HTH,
Rob. 

Asya Kamsky

unread,
Oct 19, 2013, 1:24:31 PM10/19/13
to mongodb-user
The problem is that projection $elemMatch will only return the first matching array document.

This is a problem with schema design - normally if you embed a bunch of objects in an array you will want to get all of them back when you fetch the document.  If you don't want all the documents then a different schema is probably indicated.

Asya



--
--
You received this message because you are subscribed to the Google
Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com
To unsubscribe from this group, send email to
mongodb-user...@googlegroups.com
See also the IRC channel -- freenode.net#mongodb
 
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply all
Reply to author
Forward
0 new messages