MongoDB, общая часть 2 запросов

Я получил документ, который выглядит так

@Document(collection="myDocument")
public class MyDocument {
    @Id
    private String id;

    private List<Dates> dates;
}

public class Dates{
    private String key;     
    private DateTime value;
}

А также OtherDocument является контейнером для значений DateTime из различных источников, я не могу просто сделать такие поля, как DateTime birthdate; внутри MyDocument потому что я не знаю что key будет, они просто некоторые даты, которые описывают MyDocument, Теперь мне нужно создать поисковую систему для этих значений, например, кто-то хочет найти все MyDocuments с dates который содержит:
key: "Дата рождения" больше, чем
value: "1990-01-01 00:00:00 +00:00"
а также
key: День рождения Мазера меньше
value: "1975-01-01 00:00:00 +00:00"

Так, Criteria (с помощью MongoTemplate вот) сначала может выглядеть вот так

Criteria criteria = Criteria.where("myDocument.dates.value")
    .exists(true)
    .gt(DateTimeUtil.valueOf("1990-01-01 00:00:00 +00:00"))  //just converting String to DateTime here      
    .and("myDocument.dates.name")
    .exists(true)
    .all("Birthday"));

И второй:

 Criteria criteria = Criteria.where("myDocument.dates.value")
     .exists(true)
     .lt(DateTimeUtil.valueOf("1975-01-01 00:00:00 +00:00"))  
     .and("myDocument.dates.name")
     .exists(true)
     .all("Mather's birthday"));

Проблема в том, что я не могу поставить эти оба Criteria в одной Query, это вызовет ошибку. Единственное, что я нашел до сих пор, это сделать 2 отдельных Query в этом случае, а затем найти общую часть с помощьюresultA.retainAll(resultB)

Но дело в том, что я не хочу, чтобы в этой базе данных хранилось много данных, и эти запросы будут очень частыми. Мне нужно, чтобы это работало быстро, и объединение двух списков в чистой Java будет чертовски медленным с таким количеством данных. Есть идеи, как с этим бороться?

edit # вот ошибка, выдаваемая при попытке объединить 2 Criteria как это в одном Query

пойман: (java.lang.RuntimeException), msg(json не может сериализовать тип: класс org.joda.time.DateTime) java.lang.RuntimeException: json не может сериализовать тип: класс org.joda.time.DateTime

1 ответ

Решение

Вы можете использовать приведенный ниже код. $and запрос вместе и использовать $elemMatch чтобы сопоставить поля дат по нескольким условиям.

Что-то вроде

Criteria criteria1 = Criteria.where("dates").
    elemMatch(
      Criteria.where("value").exists(true).gt(DateTimeUtil.valueOf("1990-01-01 00:00:00 +00:00"))
      .and("name").exists(true).all("Birthday")
);
Criteria criteria2 = Criteria.where("dates").
    elemMatch(
      Criteria.where("value").exists(true).lt(DateTimeUtil.valueOf("1975-01-01 00:00:00 +00:00"))
       .and("name").exists(true).all("Mather's birthday")
);
Criteria criteria = new Criteria().andOperator(criteria1, criteria2);

Примечание: у вас все еще может быть проблема с преобразованием времени в joda.

Другие вопросы по тегам