Open SledgeHammer01 opened 3 years ago
Spent a few hours debugging this :). Seems like there are several issues in play:
public BooleanExpression in(T... right) {
if (right.length == 1) {
return eq(right[0]);
} else {
return Expressions.booleanOperation(Ops.IN, mixin, ConstantImpl.create(ImmutableList.copyOf(right)));
}
}
So it looks like if you only have a single item in the array/collection, it will switch to an $eq instead. Not sure why you'd want to do that, but... :).
In my model, I currently pull the field down as a String[], which will fail in MongodbSerializer::visit because there is a check there to make sure its a collection class. So an array will fail.
If I switch my model to a List<String>
, which I guess it should have been, then the QListing property becomes a ListPath which seems to drop the in operator entirely :).
So, long story short, there seems to be a few options to get this to work "as is":
keep the model as a String[] (which isn't really "the Spring way" it seems)
in the service layer, convert it to a List<String>
use builder.and(Expressions.booleanOperation(Ops.IN, QListing.listing.amenities, ConstantImpl.create(amenities))); to bypass the 1 item "feature"
OR
switch the model to a List
Using spring-data-mongodb 3.1.2, my repo looks like:
The doc has a field thats a string array:
"amenities": ["TV", "Cable TV",
I'm trying to build a dynamic query with dsl, so something like:
This resulted in: find using query: { "amenities" : ["Wifi2"]}, which is wrong since its missing the whole $in portion. I stepped through the code and found there is a code path in there that if you have only 1 element, you change it to an eq. So I tried 2. I also tried bypassing the whole thing with:
builder.and(Expressions.booleanOperation(Ops.IN, QListing.listing.amenities, ConstantImpl.create(amenities)));
and got the same result. No $in.
How can we get the $in to work on an array with a dynamic query at runtime? I do also need to have pageable support :).
Thanks.