Morphia MongoDB 检查 null 和不存在的字段

Morphia MongoDB check for null and non existing field

我是 Morphia 和 MongoDB 的新手。有没有办法使用 Morphia 检查我的数据库中的某个字段不是 null 并且也存在。例如,来自数据库中用户集合的用户的以下记录:

{ "_id" : ObjectId("51398e6e30044a944cc23e2e"), 
  "age" : 21 , 
  "createdDate" : ISODate("2013-03-08T07:08:30.168Z"),
  "name" : "Some name" }

我如何使用 Morphia 查询来检查字段 "createdDate" 是否不为空且存在。

编辑: 我正在寻找 Morphia 的解决方案。到目前为止,我想出了这个:

query.and(query.criteria("createdDate").exists(),
query.criteria("createdDate").notEqual(null));

从文档中,我了解到 Morphia 不存储空字段或 null 字段。因此 notEqual(null).

的理由

编辑 2: 从答案中我可以看出问题需要更多解释。我无法修改 createdDate。详细说明:上面的例子没有我的实际问题复杂。我真正的问题有我无法修改的敏感字段。另外让事情变得更复杂一点,我无法控制模型,否则我可以使用其中一个答案中建议的 @PrePersist

当我无法控制模型并且不允许修改字段时,有没有办法检查空字段和不存在字段?

在 mongo 中,您可以使用此查询:

db.MyCollection.find({"myField" : {$ne : null}})

此查询将 return 个具有字段 'myField' 且值不为空的对象。

documentation 开始,Morphia 不存储 Null/Empty 值(默认情况下),因此查询

query.and(
    query.criteria("createdDate").exists(),
    query.criteria("createdDate").notEqual(null)
);

将不起作用,因为您似乎无法查询 null,但可以查询特定值。

但是,由于您只能查询特定值,因此您可以设计一个解决方法,您可以使用模型中从未使用过的日期值更新 createdDate 字段。例如,如果您用 0 初始化 Date 对象,它将被设置为纪元的开始,1970 年 1 月 1 日 00:00:00 UTC。您获得的时间是本地化时间偏移量。如果您的更新仅涉及修改 mongo shell 中的匹配元素就足够了,因此它看起来类似于:

db.users.update(
    {"createdDate": null }, 
    { "$set": {"createdDate": new Date(0)} }
)

然后您可以使用 Fluent Interface 查询该特定值:

Query<User> query = mongoDataStore
    .find(User.class)    
    .field("createdDate").exists()
    .field("createdDate").hasThisOne(new Date(0));

在定义模型时包含更新 createdDate 字段的 prePersist 方法会简单得多。该方法标有 @PrePersist 注释,以便在保存之前在订单上设置日期。 @PostPersist@PreLoad@PostLoad.

存在等效注释
@Entity(value="users", noClassNameStored = true)
public class User {

    // Properties
    private Date createdDate;

    ...
    // Getters and setters
    ..

    @PrePersist
    public void prePersist() {
        this.createdDate = (createdDate == null) ? new Date() : createdDate;
    }
}

当您第一次创建 Morphia 实例时,在调用 morphia.mapPackage() 之前执行此操作:

morphia.getMapper().getOptions().setStoreNulls(true);

让 Morphia 存储空值。

无论如何,您应该能够通过以下方式查询非空值:

query.field("createdDate").notEqual(null);