2015-05-01 3 views
2

Я новичок как в Morphia, так и в MongoDB. Есть ли способ проверить с помощью Morphia, что определенное поле в моей базе данных не является null, а также существует. Например, из следующей записи пользователя из коллекции пользователей в базе:Morphia MongoDB проверить нулевое и не существующее поле

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

Как бы использовать запрос морфия, чтобы проверить, если поле "createdDate" не равно нулю и существует.

EDIT: Я ищу решение в Морфии. До сих пор я придумал следующее:

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

Из документации я узнал, что Morphia не хранит пустое или нулевое поля. Отсюда и обоснование для notEqual(null).

EDIT 2: Из ответов я вижу, что проблема требует большего объяснения. Я не могу изменить createdDate. Чтобы разработать: приведенный выше пример менее сложный, чем моя фактическая проблема. У моей реальной проблемы есть чувствительные поля, которые я не могу изменить. Кроме того, чтобы усложнить ситуацию немного, у меня нет контроля над моделью, иначе я мог бы использовать @PrePersist, как было предложено в одном из ответов.

Есть ли способ проверить нулевое и не существующее поле, если у меня нет контроля над моделью, и мне не разрешено изменять поля?

ответ

2

С documentation, Морфий не хранит Null/пустые значения (по умолчанию), так что запрос

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

не будет работать, так как вы, кажется, не в состоянии запросить на нуль, но может запросить для конкретное значение.

Однако, поскольку вы можете запросить только определенное значение, вы можете разработать обходное решение, в котором вы можете обновить поле createdDate с использованием значения даты, которое никогда не используется в вашей модели. Например, если вы инициализируете объект Date с помощью 0, он будет установлен в начале эпохи, 1 января 1970 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)); 

Было бы намного проще при определении вашей модели включить метод 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; 
    } 
} 
+0

Спасибо, что указали мою ошибку и подробное объяснение обходного пути. Однако есть один улов, я не могу изменить 'createdDate'. Чтобы разработать: приведенный выше пример менее сложный, чем моя фактическая проблема. У моей реальной проблемы есть чувствительные поля, которые я не могу изменить. Также, чтобы усложнить ситуацию немного, у меня нет контроля над моделью, иначе я согласен с вашим решением '@ PrePersist'. Есть ли другой способ обхода? – Segmented

+0

@Segmented Боюсь, я не знаю никого другого обходного пути за пределами вышеприведенного, похоже, что изменение документов - это путь, но потом снова это не поддается контролю. Я мог только подумать о другом обходном пути, где вы можете запросить документы, где 'createdDate' существует AND, и не попадает в определенный диапазон дат, скажем, между настоящим и началом эпохи, то есть новой Date (0). Таким образом, вы можете поймать нулевые значения? – chridam

+1

Большое вам спасибо за то, что вы со мной и мои сложные проблемы. Насколько ваше решение кажется мне заманчивым (о 'createdDate' попадает в определенный диапазон дат), мне бы хотелось найти какое-то общее решение. Я надеюсь, что с вами все в порядке, прежде чем я приму решение ... – Segmented

0

В Монго вы можете использовать этот запрос:

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

Этот запрос будет возвращать объекты, которые имеют поле «MyField» и имеет значение, которое не равно нулю.

+0

спасибо за ответ! есть ли способ Морфий сделать это? – Segmented

0

При создании экземпляра морфий, перед вызовом morphia.mapPackage() сделать это:

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

иметь нулевые значения Morphia магазин.

Во всяком случае, вы должны быть в состоянии запросить ненулевые значения с:

query.field("createdDate").notEqual(null); 
Смежные вопросы