Daniel May
Daniel May

Reputation: 2262

How to match mongoid documents using array fields in query?

I am trying to match documents with Mongoid/Mongodb where array fields are used in the query. I've been struggling with $elemMatch but can't seem to get it.

Context

Example

Given a Project document from Rails console:

[#<Project _id: 4f44355a9f5b7f385a000003, 
  _type: nil, name: "Project ABC", 
  desc: "some description", 
  admin_ids: 
    [BSON::ObjectId('123')], 
  member_ids: 
    [BSON::ObjectId('456'),
    BSON::ObjectId('789')], 
  reader_ids: []
>]

I had the following code:

@projects = Project.any_of({:admin_ids => [current_user.id]}, 
                           {:member_ids => [current_user.id]}).entries

Which matches current_user.id across either admin_ids and member_ids as long as there was only a single value in either of the arrays. As per the code above:

$elemMatch

Based on researching, I think I should be using $elemMatch but am missing something.

As per the Project document code above:

// test case: this works with array of one
Project.all(conditions: {:admin_ids => "123"}).entries

// failure case: empty result   
Project.all(conditions: {:member_ids => {'$elemMatch' => {:id => '456' } }}).entries

// failure case: empty result
Project.all(conditions: {:member_ids => {'$elemMatch' => {:id => BSON::ObjectId('4f44a4019f5b7f3d5200000d') } }}).entries

Upvotes: 5

Views: 9767

Answers (2)

rubish
rubish

Reputation: 10907

You need to get rid of the array while querying.

@projects = Project.any_of({:admin_ids => current_user.id}, 
                       {:member_ids => current_user.id}).entries

That should work.

Upvotes: 11

Russell
Russell

Reputation: 12439

I think you should just be able to use $in rather than $elemMatch - as the mongodocs say:

"You only need to use [$elemMatch] when more than one field must be matched in the array element."

Have you tried something like the following?

Project.any_in(:member_ids =>  [ member_id_one, member_id_two ])

Upvotes: 11

Related Questions