如何处理 MongoDB / Morphia 中的查询迁移?

How to handle query migration in MongoDB / Morphia?

我最近不得不引入 关于 "users" collection 我的数据结构的变化,这导致了从以下简化示例的迁移:

{ 
   "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”字段从一个简单的字符串数组更改为一个复杂的 objects 数组,每个数组都有一个字段 "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里面的文档有的还是用"old"的方式存储的,有的已经用"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?

到目前为止我能想到的最好的事情是使用 "or" 查询并查询禁用验证的两个字段(否则抛出异常):

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 中执行相当复杂的逻辑来查找文档并将其转换为新格式。你可以 运行 它只能在仍然有旧 'emails' 字段的文档上,如果你有一个关于该字段的索引和数百万文档