Java 获取所有数组元素不在日期范围内的MongoDB文档
我正在学习Springboot和MongoDB 我有这个模型课:Java 获取所有数组元素不在日期范围内的MongoDB文档,java,mongodb,spring-boot,spring-data-mongodb,querydsl,Java,Mongodb,Spring Boot,Spring Data Mongodb,Querydsl,我正在学习Springboot和MongoDB 我有这个模型课: @Data @Document(collection = "accommodations") public class Accommodation { @Id private String accommodationId; @TextIndexed private String title; @Indexed private double pricePerNight; pr
@Data
@Document(collection = "accommodations")
public class Accommodation {
@Id
private String accommodationId;
@TextIndexed
private String title;
@Indexed
private double pricePerNight;
private int guests;
@Indexed
private double rating;
private AccommodationType type;
private String description;
private boolean listed;
private Address address;
private Landlord landlord;
private List<Image> images;
private List<Review> reviews;
private List<Booking> bookings;
public Accommodation(String title, double pricePerNight, int guests, AccommodationType type, String description, Address address, Landlord landlord) {
this.title = title;
this.pricePerNight = pricePerNight;
this.guests = guests;
this.type = type;
this.description = description;
this.listed = true;
this.address = address;
this.landlord = landlord;
this.rating = 0.0;
this.images = new ArrayList<>();
this.reviews = new ArrayList<>();
this.bookings = new ArrayList<>();
}
public boolean isAvailableBetween(LocalDate checkin, LocalDate checkout) {
return this.bookings
.stream()
.noneMatch(b -> (b.getCheckin().isBefore(checkout) || b.getCheckin().isEqual(checkout)) &&
(b.getCheckout().isAfter(checkin)) || b.getCheckout().isEqual(checkin));
}
}
@数据
@文件(收集=“住宿”)
公共舱位{
@身份证
私人字符串调节ID;
@文本索引
私有字符串标题;
@索引
私人双价每晚;
私人客人;
@索引
私人双重评级;
私人住宿类型;
私有字符串描述;
私有布尔列表;
私人地址;
私人业主;
私有列表图像;
私人名单审查;
私人名单预订;
公共住宿(字符串标题、每晚双倍价格、国际客人、住宿类型、字符串描述、地址、房东){
this.title=标题;
this.pricePerNight=pricePerNight;
这个。客人=客人;
this.type=type;
this.description=描述;
此参数为true;
this.address=地址;
这个。房东=房东;
该额定值=0.0;
this.images=new ArrayList();
this.reviews=new ArrayList();
this.bookings=new ArrayList();
}
公共布尔值isAvailableBetween(LocalDate签入、LocalDate签出){
还这个。预订
.stream()
.noneMatch(b->(b.getCheckin().isBefore(签出)| | b.getCheckin().isEqual(签出))&&
(b.getCheckout().isAfter(checkin))| | b.getCheckout().isEqual(checkin));
}
}
我目前正在使用“isAvailableBetween”方法过滤在特定日期范围内(签入和签出)已预订的住宿
我希望通过Mongo查询实现同样的功能,但不知道如何实现
这就是我迄今为止所尝试的(忽略查询中的其他筛选器):
@存储库
公共接口存储库扩展了MongoRepository、QueryDSL谓词执行器{
@查询(“{”+
“$and:[”+
{listed:true}+
{pricePerNight:{$lte:?0}}+
{来宾:{$gte:?1}}+
{评级:{$gte:?2}}+
“{'lown.trusted':?3},”+
{预订:{$not:{$elemMatch:{$checkin:{$lte:?5},签出:{$gte:?4}+
"]" +
"}")
Page FindAcomdationsByFilter(可分页、可分页、,
每晚双倍价格,
Integer嘉宾,
双重评级,
布尔信任,
LocalDate签入,
本地日期签出
}
还尝试将QueryDSL和Mongo标准与Spring数据MongoDB一起使用,但无法找到与“isAvailableBetween”相同的结果
有人知道怎么做吗?在进一步研究Mongo标准后,我找到了一个解决方案
public Page<Accommodation> findAccommodationsByFilter(AccommodationFilter filter, Pageable pageable) {
Criteria listedTrue = where("listed").is(true);
Query query = query(listedTrue);
filter.pricePerNight().map(where("pricePerNight")::lte).ifPresent(query::addCriteria);
filter.guests().map(where("guests")::gte).ifPresent(query::addCriteria);
filter.type().map(where("type")::is).ifPresent(query::addCriteria);
filter.rating().map(where("rating")::gte).ifPresent(query::addCriteria);
filter.trustedLandlord().map(where("landlord.trusted")::is).ifPresent(query::addCriteria);
filter.country().map(where("address.country")::is).ifPresent(query::addCriteria);
filter.city().map(where("address.city")::is).ifPresent(query::addCriteria);
if(filter.checkout().isPresent() && filter.checkin().isPresent()){
Criteria c = where("bookings")
.not()
.elemMatch(where("checkin").lte(filter.checkout().get())
.and("checkout").gte(filter.checkin().get()));
query.addCriteria(c);
}
long total = this.mongoOperations.count(query, Accommodation.class);
query.with(pageable);
List<Accommodation> accommodations = this.mongoOperations.find(query, Accommodation.class);
return new PageImpl<>(accommodations, pageable, total);
}
public Page findaccomodationsbyfilter(调节过滤器,可分页){
列出的标准true=其中(“列出”)为(真);
查询=查询(listedTrue);
filter.pricePerNight().map(其中(“pricePerNight”)::lte.ifPresent(查询::addCriteria);
filter.guests().map(其中(“guests”)::gte.ifPresent(查询::addCriteria);
filter.type().map(其中(“type”)::is).ifPresent(query::addCriteria);
filter.rating().map(其中(“rating”)::gte.ifPresent(查询::addCriteria);
filter.trustedLown().map(其中(“lown.trusted”)::is).ifPresent(query::addCriteria);
filter.country().map(其中(“address.country”)::is.ifPresent(查询::addCriteria);
filter.city().map(其中(“address.city”)::is.ifPresent(查询::addCriteria);
if(filter.checkout().isPresent()&&filter.checkin().isPresent()){
标准c=其中(“预订”)
.不是()
.elemMatch(其中(“签入”).lte(filter.checkout().get())
.and(“checkout”).gte(filter.checkin().get());
查询条件(c);
}
long total=this.mongoOperations.count(查询、住宿、类);
查询.with(可分页);
List accountations=this.mongoOperations.find(查询,accountations.class);
返回新的PageImpl(住宿、可寻呼、总计);
}
这实现了与@Query相同的功能,并增加了一个优点,即参数可以是可选的
public Page<Accommodation> findAccommodationsByFilter(AccommodationFilter filter, Pageable pageable) {
Criteria listedTrue = where("listed").is(true);
Query query = query(listedTrue);
filter.pricePerNight().map(where("pricePerNight")::lte).ifPresent(query::addCriteria);
filter.guests().map(where("guests")::gte).ifPresent(query::addCriteria);
filter.type().map(where("type")::is).ifPresent(query::addCriteria);
filter.rating().map(where("rating")::gte).ifPresent(query::addCriteria);
filter.trustedLandlord().map(where("landlord.trusted")::is).ifPresent(query::addCriteria);
filter.country().map(where("address.country")::is).ifPresent(query::addCriteria);
filter.city().map(where("address.city")::is).ifPresent(query::addCriteria);
if(filter.checkout().isPresent() && filter.checkin().isPresent()){
Criteria c = where("bookings")
.not()
.elemMatch(where("checkin").lte(filter.checkout().get())
.and("checkout").gte(filter.checkin().get()));
query.addCriteria(c);
}
long total = this.mongoOperations.count(query, Accommodation.class);
query.with(pageable);
List<Accommodation> accommodations = this.mongoOperations.find(query, Accommodation.class);
return new PageImpl<>(accommodations, pageable, total);
}