Поскольку формат даты для поля документа Date_Of_Birth
и вводимые даты в строковых данных и отформатированы как "MM / dd / yyyy", сравнение не будет правильным, если используется как они есть. Существуют различные способы решения этой проблемы.
Преобразование обоих форматов даты в строки "гггг / мм / дд", сравнение или , преобразование обеих дат в Date
объектов и сравнение. Обратите внимание, что в примере кода показано использование значений даты, преобразованных в Date
объекты.
Чтобы преобразовать даты для запроса find
, фильтр будет использовать оператор агрегирования даты или преобразования строк. Фильтр запросов find
может использовать операторы агрегации только с оператором * 1014. *
Я не могу понять, ясно ли использовать $expr
с API-интерфейсами Spring-Data MongoDB (я подозреваю, что такого API для обработки не существует $expr
, но для этого может существовать обходной путь).
Чтобы четко выполнить запрос, используйте агрегацию. Ниже приведены версии Mon go Shell и Spring Data.
db.persons.aggregate( [
{
$addFields: {
matches: {
$and: [
{ $gte: [
{ $dateFromString: { dateString: "$record.Date_Of_Birth", format: "%m/%d/%Y" } },
ISODate("2018-09-24T00:00:00.00Z") // input from date
] },
{ $lte: [
{ $dateFromString: { dateString: "$record.Date_Of_Birth", format: "%m/%d/%Y" } },
ISODate("2018-11-10T00:00:00.00Z") // input to date
] }
]
}
}
},
{
$match: { matches: true }
}
] )
Spring-Data Java код:
// Convert the String input dates to Date objects to be used in the query
String from = "9/24/2018";
String to = "11/10/2018";
DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date fromDt = dateFormat.parse(from);
Date toDt = dateFormat.parse(to);
// Build and run the query
MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "test");
Aggregation agg = newAggregation(
project("record.Date_Of_Birth")
.and(Gte.valueOf(DateOperators.DateFromString.fromStringOf("record.Date_Of_Birth").withFormat("%m/%d/%Y"))
.greaterThanEqualToValue(fromDt))
.as("matches1")
.and(Lte.valueOf(DateOperators.DateFromString.fromStringOf("record.Date_Of_Birth").withFormat("%m/%d/%Y"))
.lessThanEqualToValue(toDt))
.as("matches2"),
match(where("matches1").is(true)),
match(where("matches2").is(true))
);
AggregationResults<Person> results = mongoOps.aggregate(agg, "persons", Person.class);
results.forEach(System.out::println);