13

I need a way to search but not include an _id which is already on the screen in front of the user. For example, I have 3 pet profiles one which the user is already viewing.

On that page I have a heading called My Family. I then run this search:

public function fetch_family($owner)
    {
        $collection = static::db()->mypet;
        $cursor = $collection->find(array('owner' => new MongoId($owner)));

        if ($cursor->count() > 0)
            {
                $family = array();
                // iterate through the results
                while( $cursor->hasNext() ) {   
                    $family[] = ($cursor->getNext());
                }
                return $family;
            }
    }

And it returns all the pets in my family even knowing I am already showing one. So I want to exclude that one _id from the search.

I thought something like this.

$cursor = $collection->find(array('owner' => new MongoId($owner), '$not'=>array('_id'=>new MongoId(INSERT ID HERE))));

However, that just stops the whole thing from running.

halfer
  • 19,824
  • 17
  • 99
  • 186
RussellHarrower
  • 6,470
  • 21
  • 102
  • 204
  • This is a good question, and I needed this info too, but you might consider doing this on the client side to save the server from the (very small) load of considering the object _id? – Will Brickner Mar 01 '17 at 04:55

2 Answers2

28

You need to do a $ne (not equal) to make sure the current pet you are viewing is excluded from the search by owner.

Example in the mongo shell:

var viewingPetId = ObjectId("515535b6760fe8735f5f6899");
var ownerId = ObjectId("515535ba760fe8735f5f689a");

db.mypet.find(
    {
        _id: { $ne: viewingPetId },
        owner: ownerId
    }
)
Stennie
  • 63,885
  • 14
  • 149
  • 175
8

Use $ne as (notice no need to use ObjectId(), string will autocast to ObjectId):

db.organizations.find({"_id" : {$ne:"563c50e05cdb2be30391e873"}})
MBehtemam
  • 7,865
  • 15
  • 66
  • 108
Aqib Mumtaz
  • 4,936
  • 1
  • 36
  • 33
  • 1
    Thus is just the same as what the provided answer says, so there is no need to add another one. Also as long as the schema type is present ( and always is for `_id` ) then mongoose will autocast from string anyway, which means an explicit conversion is not required. – Blakes Seven Nov 07 '15 at 02:23
  • I added it because I was getting "ObjectId not resolved error". What do you mean by autocast? do you mean db.organizations.find({"_id" : {$ne:"563c50e05cdb2be30391e873"}}) is sufficient? – Aqib Mumtaz Nov 07 '15 at 02:56
  • Yes. Mongoose will take that string and convert it to an `ObjectId` automatically. You can see how it does this and the query sent to the server by enabling debugging. `mongoose.set('debug',true)` – Blakes Seven Nov 07 '15 at 03:12
  • Thanks, thats the right suggestion, answer updated as per your suggestion. – Aqib Mumtaz Nov 07 '15 at 05:05
  • how about using $nin with array of string? – Filip Bartuzi Jun 20 '17 at 11:46