0

我有这样的 mongodb 文档,并想从 resource_well 中的未发布数组中删除一个元素

{
       "_id": ObjectId("4fa77c808d0a6c287d00000a"),       
       "production_status": "Unscheduled",
       "projected_air_date": null,
       "published": false,
       "resource_well": {
         "published": [

        ],
         "unpublished": {
           "0": ObjectId("4fa795038d0a6c327e00000e"),
           "1": ObjectId("4fa795318d0a6c327e00000f"),
           "2": ObjectId("4fa795508d0a6c327e000011"),
           "3": ObjectId("4fa796f48d0a6c327e000013")
        }
      },
       "segment_status": "Draft",
}

控制器中的代码

segment = Segment.find(params[:segment_id])
# segment.resource_well[params['resource_well_type']].class => Array   
# segment.resource_well[params['resource_well_type']].inspect => [BSON::ObjectId('4fa795038d0a6c327e00000e'), BSON::ObjectId('4fa795318d0a6c327e00000f'), BSON::ObjectId('4fa795508d0a6c327e000011'), BSON::ObjectId('4fa796f48d0a6c327e000013')]  
segment.resource_well[params['resource_well_type']].delete(params[:asset_ids])
segment.save

无法删除元素形式的数组

4

2 回答 2

4

您的 ODM(或 ORM)为您提供关联,以便您可以利用 ODM 为您管理链接。因此,您应该使用关联,否则您将面临上吊的风险。只要确保正确指定关系,并使用关联命名的生成方法及其方法,例如resource_well.unpublished <<,resource_well.unpublished.delete。以下模型和测试对我有用。不便之处在于关联上的 delete 方法采用对象,例如 other.delete(object) 而不是字符串或条件,因此如果您以字符串开头,则必须提供对象才能删除它。请注意, other.delete_all(conditions) 或 other.where(conditions).delete_all 会删除实际文档以及关联,这不是您要查找的内容。反正,

楷模

class Segment
  include Mongoid::Document
  field :production_status, type: String
  field :projected_air_date, type: Date
  field :published, type: Boolean
  field :segment_status, type: String
  embeds_one :resource_well
end

class ResourceWell
  include Mongoid::Document
  embedded_in :segment
  has_and_belongs_to_many :published, :class_name => 'Resource'
  has_and_belongs_to_many :unpublished, :class_name => 'Resource'
end

class Resource
  include Mongoid::Document
  field :name, type: String
end

测试

require 'test_helper'

class Object
  def to_pretty_json
     JSON.pretty_generate(JSON.parse(self.to_json))
  end
end

class SegmentTest < ActiveSupport::TestCase
  def setup
    Segment.delete_all
  end

  test 'resource_well unpublished delete' do
    res = (0..3).collect{|i| Resource.create(name: "resource #{i}")}
    seg = Segment.create(
        production_status: 'Unscheduled',
        projected_air_date: nil,
        published: false,
        resource_well: ResourceWell.new(unpublished: res[0..2]),
        segment_status: 'Draft')
    seg.resource_well.unpublished << res[3] #just an append example
    puts seg.to_pretty_json

    id = res[0]['_id'].to_s
    puts "id: #{id}"
    resource_obj = Resource.find(id)
    puts "resource: #{resource_obj.inspect}"
    Rails.logger.debug("delete: #{resource_obj.inspect}")
    seg.resource_well.unpublished.delete(resource_obj)
    puts Segment.find(:all).to_pretty_json
  end
end

结果

# Running tests:

{
  "_id": "4fa839197f11ba80a9000006",
  "production_status": "Unscheduled",
  "projected_air_date": null,
  "published": false,
  "resource_well": {
    "_id": "4fa839197f11ba80a9000005",
    "published_ids": [

    ],
    "unpublished_ids": [
      "4fa839197f11ba80a9000001",
      "4fa839197f11ba80a9000002",
      "4fa839197f11ba80a9000003",
      "4fa839197f11ba80a9000004"
    ]
  },
  "segment_status": "Draft"
}
id: 4fa839197f11ba80a9000001
resource: #<Resource _id: 4fa839197f11ba80a9000001, _type: nil, name: "resource 0">
[
  {
    "_id": "4fa839197f11ba80a9000006",
    "production_status": "Unscheduled",
    "projected_air_date": null,
    "published": false,
    "resource_well": {
      "_id": "4fa839197f11ba80a9000005",
      "published_ids": [

      ],
      "unpublished_ids": [
        "4fa839197f11ba80a9000002",
        "4fa839197f11ba80a9000003",
        "4fa839197f11ba80a9000004"
      ]
    },
    "segment_status": "Draft"
  }
]
.

Finished tests in 0.016026s, 62.3986 tests/s, 0.0000 assertions/s.

1 tests, 0 assertions, 0 failures, 0 errors, 0 skips
于 2012-05-07T21:24:43.107 回答
2
db.collection.update( 
  {_id : ObjectId("4fa77c808d0a6c287d00000a")}, 
  { $unset : { "resource_well.unpublished.1" : 1 }} 
);

这将删除数组的元素 [1]。

您还可以阅读如何使用 mongoid 实现它:http: //mongoid.org/docs/upgrading.html

于 2012-05-07T13:00:49.057 回答