0

mongo中的document结构如下

Project(@Entity)
  |--Deliverables(@Embedded, list inside Project)
       |--DeliveryTypes(@Embedded, list inside Deliverables)
            |--DeliveryItems(Plain list inside DeliveryTypes)
                 |--log(Plain list inside DeliveryItems)

mongo中其他可能的文档结构如下

Project(@Entity)
  |--Deliverables(@Embedded, list inside Project)
       |--DeliveryTypes(@Embedded, list inside Deliverables)
            |--DeliveryItems(Plain list inside DeliveryTypes)
                 |--Tasks(Plain list inside DeliveryItems)
                      |--log(Plain list inside Tasks)
                 |--log(Plain list inside DeliveryItems)

这是项目文档在 mongoDB 中的样子

{
"_id" : ObjectId("51827f4fe4b07cc5088149ff"),
"className" : "Project",
"name" : "TestProject",
"description" : "This is a test project",
"state" : "Open",
"dateCreated" : ISODate("2013-05-02T14:59:27.069Z"),
"projectStatuses" : [
    {
        "status" : "On Track",
        "dateCreated" : ISODate("2013-05-02T14:59:27.071Z"),
        "user" : {
                   "_id" : "testUser@abc.com",
                   "firstName" : "Test",
                   "lastName" : "User",
                   "enabled" : true,
                   "accountExpired" : false,
                   "accountLocked" : false,
                   "passwordExpired" : false
                 }
    }
],
"commercialStatuses" : [
    {
        "status" : "On Track",
        "dateCreated" : ISODate("2013-05-02T14:59:27.074Z"),
        "user" : {
                   "_id" : "testUser@abc.com",
                   "firstName" : "Test",
                   "lastName" : "User",
                   "enabled" : true,
                   "accountExpired" : false,
                   "accountLocked" : false,
                   "passwordExpired" : false
                 }
    }
],
"deliverables" : [
    {
        "embeddedId" : ObjectId("5183702fe4b014bfbe387d37"),
        "name" : "TestSite 01",
        "deliveryTypes" : [
            {
                "deliveryItems" : [
                    {
                        "embeddedId" : ObjectId("5183702fe4b014bf00000003"),
                        "type" : "Plain",
                        "log" : [
                            {
                                "dateCreated" : ISODate("2013-05-03T08:42:10.592Z"),
                                "oldValue" : "Open",
                                "newValue" : "Closed",
                                "user" : {
                                           "_id" : "testUser@abc.com",
                                           "firstName" : "Test",
                                           "lastName" : "User",
                                           "enabled" : true,
                                           "accountExpired" : false,
                                           "accountLocked" : false,
                                           "passwordExpired" : false
                                          }
                            },
                            {
                                "dateCreated" : ISODate("2013-05-03T09:24:30.336Z"),
                                "oldValue" : "Closed",
                                "newValue" : "Open",
                                "user" : {
                                           "_id" : "testUser@abc.com",
                                           "firstName" : "Test",
                                           "lastName" : "User",
                                           "enabled" : true,
                                           "accountExpired" : false,
                                           "accountLocked" : false,
                                           "passwordExpired" : false
                                         }
                            },
                            {
                                "dateCreated" : ISODate("2013-05-03T13:33:06.550Z"),
                                "oldValue" : "Open",
                                "newValue" : "Closed",
                                "user" : {
                                           "_id" : "testUser@abc.com",
                                           "firstName" : "Test",
                                           "lastName" : "User",
                                           "enabled" : true,
                                           "accountExpired" : false,
                                           "accountLocked" : false,
                                           "passwordExpired" : false
                                         }
                            }
                        ]
                    },
                    {
                        "embeddedId" : ObjectId("5183702fe4b014bf00000004"),
                        "type" : "task",
                        "tasks" : [
                            {
                                "embeddedId" : ObjectId("518370abe4b014bf00000001"),
                                "name" : "TestSubTask 1",
                                "log" : [
                                    {
                                        "dateCreated" : ISODate("2013-05-03T08:09:15.624Z"),
                                        "oldValue" : "Open",
                                        "newValue" : "Created",
                                        "user" : {
                                                  "_id" : "testUser@abc.com",
                                                  "firstName" : "Test",
                                                  "lastName" : "User",
                                                  "enabled" : true,
                                                  "accountExpired" : false,
                                                  "accountLocked" : false,
                                                  "passwordExpired" : false
                                                }
                                    }
                                ],
                                "plannedEndDate" : ISODate("2013-05-02T22:00:00Z"),
                                "assignedUser" : "Test person",
                                "description" : "This is a test sub task"
                            }
                        ],
                        "log" : [
                            {
                                "dateCreated" : ISODate("2013-05-03T08:07:52.725Z"),
                                "oldValue" : "Open",
                                "newValue" : "Closed",
                                "user" : {
                                           "_id" : "testUser@abc.com",
                                           "firstName" : "Test",
                                           "lastName" : "User",
                                           "enabled" : true,
                                           "accountExpired" : false,
                                           "accountLocked" : false,
                                           "passwordExpired" : false
                                         }
                            }
                        ]
                    }
                ]
            }
   ]
}

现在我遇到的问题,我想改变所有出现的

"user" : {
          "_id" : "testUser@abc.com",
          "firstName" : "Test",
          "lastName" : "User",
          "enabled" : true,
          "accountExpired" : false,"accountLocked" : false,
          "passwordExpired" : false
         }

在下面

projectStatuses, commercialStatuses, and log 

"user" : DBRef("User", "testUser@abc.com")

这是我到目前为止所尝试的,

Mongo connection = new Mongo("localhost", 27017)
DB db = connection.getDB('test')

DBCollection projectCollection = Project.collection
QueryBuilder projectQuery = new QueryBuilder()
BasicDBObject projectKeys = new BasicDBObject()
DBCursor projectCursor = projectCollection.find(projectQuery.get(), projectKeys)
ArrayList projects = projectCursor.toArray()

projects.each { project ->
   project.deliverables.each { deliverable ->
      deliverable.deliveryTypes.each { deliveryType ->
         deliveryType.deliveryItems.each { deliveryItem ->
            deliveryItem.log.each { log ->
               updateLogUser(log, db)
            }
         }
      }
   }
}

static updateLogUser(def log, DB db) {
    if (log.user?._id) {
        log.user = new DBRef(db, "User", log.user?._id)
    }
}

上面的代码可以满足我的需要,但现在的问题是如何保存更新后的查询对象?我尝试了以下操作,但当我尝试登录时,grails 不断抛出异常“无法将 BasicDBObject 转换为 DBRef”:/

projects.each { project ->
        Project.update(['_id': project._id]) {set "deliverables", project.deliverables}
    }

迁移后我检查了数据库,没有用户对象的实例,只有引用,但仍然得到异常。我不太擅长编写迁移脚本,所以如果有人可以帮助我如何保存查询的文档(看起来像一张大地图),那就太好了,或者一些指向操作文档的有用链接也会有所帮助。提前致谢 :)

4

1 回答 1

1

好的,我终于设法将包含 mongo 的 BasicBDObject 的嵌入列表更新为 mongo DBRef 对象。

首先,您应该使用以下代码建立连接。下面的代码连接到本地机器上端口“27017”(默认端口)的“test”数据库。

Mongo connection = new Mongo("localhost", 27017)
DB db = connection.getDB('test')

接下来编写一个查询,获取存储在 mongo 中的所有文档,这些文档需要更新,在我的例子中是所有文档。以下代码可帮助您做到这一点。

//specify which collection you want to query 
DBCollection projectCollection = Project.collection
//specify the query using the following code, in my case all 
//documents so I leave the query object empty
QueryBuilder projectQuery = new QueryBuilder()
//specify what fields of the document should be retrieved, in my case
//I need all the fields, so I leave it empty
BasicDBObject projectKeys = new BasicDBObject()
//initialize a cursor, it is more like an iterator, to the results
DBCursor projectCursor = projectCollection.find(projectQuery.get(), projectKeys)
//convert the obtained results to an ArrayList
ArrayList projects = projectCursor.toArray()

遍历结果并更新您要更新的内容

projects.each { project ->
project.deliverables.each { deliverable ->
  deliverable.deliveryTypes.each { deliveryType ->
     deliveryType.deliveryItems.each { deliveryItem ->
        deliveryItem.log.each { log ->
           updateLogUser(log.user, db)
        }
      }
    }
  }
}

static updateLogUser(def user, DB db) {
  try {
        //user.fetch is to check whether the object is BasicDBObject
        //or DBRef object. if user object is a BasicDBObject then .fetch()
        //throws an exception else it gets the referenced object
        if (user && user.fetch()) {
            return user
        } else {
            return null
        }
    } catch (Exception e) {
        return new DBRef(db, "User", user._id)
    }
}

现在保存您对文档所做的更改。

projects.each { project ->
   !project.deliverables ?: 
      Project.update(['_id': project.id]) {set "deliverables", project.deliverables}
}

由于您无法直接更新 mongodb 中的嵌套列表,这是 mongo 中的错误,并已报告给 mongo,希望他们尽快修复它,您可以更新嵌套列表的父级,在我的情况下,它是“可交付成果”列表嵌套列表的父级

于 2013-05-15T12:32:29.017 回答