java - 如何在 MongoDB/Morphia 中处理查询迁移?

标签 java mongodb migration database-migration morphia

我最近不得不引入关于“用户”集合的我的数据结构的变化,这导致了从以下简化示例的迁移:

{ 
   "name": "John",
   "emails" : [ "a@a.a", "b@b.b" ]
}

为此:

{ 
   "name": "John",
   "emailAddresses" : [ 
       { 
         "email" : "a@a.a",
         "verified" : true
       },
       { 
         "email" : "b@b.b",
         "verified" : true
       }
    ]
}

所以“emails”字段从一个简单的字符串数组变成了一个复杂对象数组,每个对象都有一个字段“email”和“verified”。除此之外,它的名称更改为“emailAddresses”。

我知道如何使用 Morphia 提供的注释(例如 @PostLoad)迁移我的有关加载和存储的数据以及更改后的数据模型。或 @NotSaved .

我的问题出在查询上。最初,我会像这样通过电子邮件地址查询用户:

Query<User> q = dataStore.createQuery(User.class);
q.filter("emails", email);
User u = q.get();

我知道我只需要使查询适应以下内容以支持我的新数据结构:

Query<User> q = dataStore.createQuery(User.class);
q.filter("emailAddresses.email", email);
User u = q.get();

没关系。问题是我 Collection 的一些文档仍然以“旧”方式存储,而一些已经以"new"方式存储。如果我只使用"new"方式,我将无法找到旧文档。

问题是:

How can I create a query that considers both old and new data structures when (like in this example) querying by email address?

到目前为止,我能想到的最好的办法是使用“或”查询并在禁用验证的情况下查询两个字段(否则会抛出异常):

Query<User> q = dataStore.createQuery(User.class);
q.disableValidation();
q.or(q.criteria("emails").equal(email), q.criteria("emailAddresses.email").equal(email)); 
User u = q.get();

However, this seems quite cumbersome and possibly bad for performance. I was wondering if there is a better way to approach this problem?

最佳答案

您不必只使用 Morphia 注释。您可以使用 MongoDB 命令行来运行更新查询。您可以在 JavaScript 中执行相当复杂的逻辑来查找文档并将其转换为新格式。如果您在该字段上有索引并且有数百万个文档,则只能在仍然具有旧“电子邮件”字段的文档上运行它

关于java - 如何在 MongoDB/Morphia 中处理查询迁移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42900900/

相关文章:

java - 如何使用 MultiMap 通过唯一属性收集 List<Map> 的属性?

java - 邻接矩阵java

php - 如何进行 OR 搜索

php - 具有不同值和排序值的 MongoDB geoNear

swift - NSLocale.currentLocale 的端口方法 swizzle 从 swift 2.3 到 swift 3

migration - Liquibase - 忽略旧的变更集

Java:LinkedList findnode() 方法和 isEmpty() 方法

java - 连接设备后Android studio界面不重绘

javascript - 异步 mongoDB find() 方法的问题

MySQL --> MongoDB : Keep IDs or create mapping?