如何在查询中使用数组字段匹配mongoid文档?

Dan*_*May 4 ruby-on-rails mongodb mongoid

我正在尝试将文档与Mongoid/Mongodb匹配,其中在查询中使用数组字段.我一直在努力,$elemMatch但似乎无法得到它.

上下文

  • 一个Project可以有admin,member,reader用户
  • 这些用户由Project(HABTM)引用
  • 我希望能够找到以下项目:
    • 用户A是 admin
    • 用户B是adminmember
    • ..等..

给出ProjectRails控制台的文档:

[#<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: []
>]
Run Code Online (Sandbox Code Playgroud)

我有以下代码:

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

它匹配current_user.id跨越要么admin_ids并且member_ids 只要有只有在任一数组的一个值.根据上面的代码:

  • 尝试匹配用户'123'给出正确的结果
  • 试图匹配用户'456'没有结果(不正确)

$ elemMatch

根据研究,我认为我应该使用$elemMatch但缺少一些东西.

根据Project上面的文档代码:

// 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
Run Code Online (Sandbox Code Playgroud)

rub*_*ish 10

你需要在查询时摆脱阵列.

@projects = Project.any_of({:admin_ids => current_user.id}, 
                       {:member_ids => current_user.id}).entries
Run Code Online (Sandbox Code Playgroud)

这应该工作.


Rus*_*ell 9

我认为你应该能够使用$in而不是$ elemMatch - 正如mongodocs所说:

" $elemMatch当数组元素中必须匹配多个字段时,你只需要使用[ ]."

你尝试过类似下面的东西吗?

Project.any_in(:member_ids =>  [ member_id_one, member_id_two ])
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以这样做:Project.where(:member_ids.in => [member_id_one,member_id_two]) (2认同)