2015-05-01 102 views
2

我是新来的都吗啡和MongoDB。有没有一种方法来检查使用吗啡,在我的数据库中的某一个领域是不是null也存在。例如从用户的集合在数据库中的用户的以下记录:吗啡MongoDB的检查null和非现有字段

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

我将如何使用吗啡查询,以检查是否领域"createdDate"不是null存在。

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

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

从技术文档,我学到了吗啡不存储空或空字段。因此为notEqual(null)的理由。

编辑2:从答案我可以看到问题需要更多的解释。我无法修改createdDate。详细说明:上面的例子并不比我的实际问题复杂。我真正的问题是我无法修改的敏感领域。另外要的东西多一点复杂,我没有在模型的控制,否则作为一个答案建议我可以用@PrePersist

有没有一种方法来检查null和非现有的现场时,我有过的模型中没有控制,我不允许修改字段?

回答

2

documentation,吗啡不存储空/空值(默认情况下),所以查询

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

是行不通的,因为它似乎你是不是能够在空查询,但也可以查询具体的价值。

但是,由于您只能查询特定值,因此可以设计一种解决方法,您可以使用在模型中从不使用的日期值更新createdDate字段。例如,如果使用0初始化Date对象,则它将被设置为时间的开始,即1970年1月1日00:00:00 UTC。你得到的时间是本地化的时间偏移量。这将是足够的,如果你的更新只涉及到修改在蒙戈外壳匹配的元素(一个或多个),因此它同样也会看这个:

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; 
    } 
} 
+0

感谢您指出我的错误并详细解释了解决方法。尽管有一个问题,我无法修改'createdDate'。详细说明:上面的例子并不比我的实际问题复杂。我真正的问题是我无法修改的敏感领域。此外,让事情复杂一点,我不能控制模型,否则我同意你的解决方案'@ PrePersist'。有其他解决方法吗? – Segmented

+0

@Segmented恐怕我不知道上面的任何其他解决方法,似乎修改文档是要走的路,但是再一次它超出了你的控制范围。我只能想到另一种解决方法,您可以查询“createdDate”存在的文档,并且不在特定的日期范围内,比如从现在到新纪元开始(即新日期(0))。这样你可以捕获空值? – chridam

+1

非常感谢你的支持和我的复杂问题。尽管你的解决方案听起来很诱人(关于'createdDate'属于特定的日期范围),我很想寻找一些通用的解决方案。在我接受你的解决方案之前,我希望你能和你在一起... – Segmented

0

在蒙戈您可以使用此查询:

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

这个查询将返回具有该领域对象的MyField的“和具有的值不为空。

+0

感谢您的回答!有没有Morphia的方法来做到这一点? – Segmented

0

当你第一次创建吗啡实例,调用morphia.mapPackage()做到这一点之前:

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

有吗啡存储空值。

无论如何,你应该能够查询非空值有:

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