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

3

我对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
当我没有控制模型并且不允许修改字段时,有没有一种方法可以检查null和不存在的字段?
3个回答

3

文档中可以看到,Morphia默认不存储null/空值,因此查询语句为:

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

由于似乎您无法在 null 上查询,因此将不起作用,但可以查询特定值。

然而,由于只能查询特定值,您可以想出一个解决方法,在其中使用从未在模型中使用过的日期值更新createdDate字段。例如,如果使用 0 初始化 Date 对象,则会将其设置为时代开始的 Jan 1st 1970 00:00:00 UTC。您获得的小时数是本地化的时区偏移量。如果您的更新仅涉及修改 mongo shell 中的匹配元素,则已足够,因此它看起来类似于这样:

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

您可以使用流畅接口来查询特定的值:

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

在定义模型时,包含一个prePersist方法来更新createdDate字段会更加简单。该方法使用@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;
    }
}

感谢您指出我的错误并详细解释了解决方法。但是有一个问题,我无法修改“createdDate”。具体来说:上面的示例比我的实际问题要简单。我的真正问题涉及到一些敏感字段,我不能修改它们。另外,为了让事情变得更加复杂,我无法控制模型,否则我同意您的“@PrePersist”解决方案。是否有其他解决方法? - Segmented
@Segmented 很抱歉,除了上述方法外,我不知道其他的解决方法。修改文档似乎是唯一的出路,但这又超出了您的控制范围。我只能想到另一个解决方法,即查询存在“createdDate”且不在特定日期范围内(例如现在和纪元开始时)的文档。这样或许可以捕获空值? - chridam
1
非常感谢您忍受我那些复杂的问题。虽然您提供的解决方案(关于createdDate在特定日期范围内)听起来很有吸引力,但我想寻找一些通用的解决方案。在我采纳您的方案之前,希望这样做对您没有问题...谢谢! - Segmented

0

当您首次创建Morphia实例时,在调用morphia.mapPackage()之前,请执行以下操作:

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

让Morphia存储空值。

无论如何,您应该能够使用以下查询非空值:

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

-1
在Mongo中,您可以使用以下查询:
db.MyCollection.find({"myField" : {$ne : null}})

这个查询将返回具有字段“myField”的对象,并且该值不为空。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接