Related
I'm developing a method in Spring-Data-MongoDB that use $facet,$addFields and $function but it return null.
This is the aggregation in MongoDB
db.utenti.aggregate([
{
$facet:
{
"aggregation": [
{
$match: { age: { $gt: 18 } }
},
{
$addFields:{
max: {
$function: {
body: function(name, scores) {
let max = Math.max(...scores);
return `Hello ${name}. Your max score is ${max}.`
},
args: [ "$name", "$scores"],
lang: "js"
}
}
}
}
]
}
}
]).pretty()
This the expected result
{
"aggregation" : [
{
"_id" : ObjectId("62c5f16b39b3d635ab6bf60d"),
"username" : "james34",
"name" : "james",
"role" : [
"user",
"specialuser"
],
"age" : 34,
"scores" : [
10,
9,
10
],
"_class" : "com.project.ecommercemongo.model.User",
"max" : "Hello james. Your max score is 10."
},
{
"_id" : ObjectId("62c5f1b839b3d635ab6bf60e"),
"username" : "elizabeth54",
"name" : "elizabeth",
"role" : [
"user",
"specialuser"
],
"age" : 54,
"scores" : [
10,
10,
10
],
"_class" : "com.project.ecommercemongo.model.User",
"max" : "Hello elizabeth. Your max score is 10."
},
{
"_id" : ObjectId("62c5f1f139b3d635ab6bf60f"),
"username" : "frank50",
"name" : "frank",
"role" : [
"user"
],
"age" : 50,
"scores" : [
10,
10,
10
],
"_class" : "com.project.ecommercemongo.model.User",
"max" : "Hello frank. Your max score is 10."
},
{
"_id" : ObjectId("62c5f27a39b3d635ab6bf610"),
"username" : "john26",
"name" : "john",
"role" : [
"user"
],
"age" : 26,
"scores" : [
8,
8,
10
],
"_class" : "com.project.ecommercemongo.model.User",
"max" : "Hello john. Your max score is 10."
}
]
}
This is the result I get
[
{
"_id": null,
"username": null,
"name": null,
"role": null,
"age": null,
"scores": null
}
]
this is the method that call facet addFields and function,but it don't add the field "max" and returns null
public List<User> aggregation1() {
List<Object> bl = new LinkedList<Object>();
bl.add("$name");
bl.add("$scores");
ScriptOperators.Function function= Function.function("function(name, scores) {let max = Math.max(...scores); return `Hello ${name}. Your max score is ${max}`}").args(bl).lang("js");//`Hello ${name}. Your max score is ${max}.`}");
System.out.println(function.toDocument());
FacetOperation facetOperation1 = Aggregation.facet(Aggregation.match(Criteria.where("age").gte(18)),Aggregation.addFields().addFieldWithValue("max", function).build()).as("aggregation");
Aggregation agg = Aggregation.newAggregation(facetOperation1);
return mongoTemplate.aggregate(agg, "utenti",User.class).getMappedResults();
}
And this is the User class
#Document(collection="utenti")
//#Sharded(shardKey = { "country", "userId" })
public class User {
#Id
private String _id;
private String username;
private String name;
private String[] role;
private Integer age;
private Integer[] scores;
public User() {
super();
}
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getRole() {
return role;
}
public void setRole(String[] role) {
this.role = role;
}
public Integer[] getScores() {
return scores;
}
public void setScores(Integer[] scores) {
this.scores = scores;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
how can i put all the users into the facet and add a field ? Thank you
Update
Now it work, I had to map the output with the aggregation fields
public List<MaxFacet> aggregation1() {
List<Object> bl = new LinkedList<Object>();
bl.add("$name");
bl.add("$scores");
ScriptOperators.Function function = Function.function(
"function(name, scores) {let max = Math.max(...scores); return `Hello ${name}. Your max score is ${max}.`}")
.args(bl).lang("js");// `Hello ${name}. Your max score is ${max}.`}");
System.out.println(function.toDocument());
FacetOperation facetOperation = Aggregation.facet().and(match(Criteria.where("age").gte(18)),
Aggregation.addFields().addFieldWithValue("max", function).build()).as("aggregation");
Aggregation agg = Aggregation.newAggregation(facetOperation);
return mongoOperations.aggregate(agg, mongoTemplate.getCollectionName(User.class), MaxFacet.class)
.getMappedResults();
}
public class MaxFacet {
private List<UserOut> aggregation;
public List<UserOut> getAggregation() {
return aggregation;
}
public void setAggregation(List<UserOut> facet1) {
this.aggregation = facet1;
}
public MaxFacet() {
// TODO Auto-generated constructor stub
}
}
#JsonPropertyOrder({"id","username","name","age","scores","max"})
public class UserOut {
#JsonProperty(value="id")
private String id;
private String username;
private String name;
private String []scores;
private String max;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getScores() {
return scores;
}
public void setScores(String[] scores) {
this.scores = scores;
}
public String getMax() {
return max;
}
public void setMax(String value) {
this.max= value;
}
}
[
{
"aggregation": [
{
"id": "62c5f16b39b3d635ab6bf60d",
"username": "james34",
"name": "james",
"scores": [
"10",
"9",
"10"
],
"max": "Hello james. Your max score is 10."
},
{
"id": "62c5f1b839b3d635ab6bf60e",
"username": "elizabeth54",
"name": "elizabeth",
"scores": [
"10",
"10",
"10"
],
"max": "Hello elizabeth. Your max score is 10."
},
{
"id": "62c5f1f139b3d635ab6bf60f",
"username": "frank50",
"name": "frank",
"scores": [
"10",
"10",
"10"
],
"max": "Hello frank. Your max score is 10."
},
{
"id": "62c5f27a39b3d635ab6bf610",
"username": "john26",
"name": "john",
"scores": [
"8",
"8",
"10"
],
"max": "Hello john. Your max score is 10."
}
]
}
]
Alternative soluition: You can simplify your code this way
1- Use inheritance mecanism for the UserOut class
public class UserOut extends User {
private String max;
public String getMax() {
return max;
}
public void setMax(String value) {
this.max= value;
}
}
2- For the complex pipelines, the custom AggregationOperation implementation is friendlier than Spring Data builder.
AggregationOperation facetOperation = ao ->
new Document("$facet",
new Document("aggregation", Arrays.asList(
new Document("$match", new Document("age", new Document("$gt", 18))),
new Document("$addFields",
new Document("max",
new Document("$function",
new Document("body", "function(name, scores) {"+
" let max = Math.max(...scores);"+
" return `Hello ${name}. Your max score is ${max}.`"+
"}")
.append("args", Arrays.asList("$name", "$scores"))
.append("lang", "js")
)
)
)
))
);
Aggregation agg = Aggregation.newAggregation(facetOperation);
return mongoOperations
.aggregate(agg, mongoTemplate.getCollectionName(User.class), MaxFacet.class)
.getMappedResults();
Alternatively, just parse your shell JSON query this way (triple quotes starting from Java 13):
Document.parse("""
{
"$facet":
{
"aggregation": [
{
"$match": { "age": { "$gt": 18 } }
},
{
"$addFields":{
"max": {
"$function": {
"body": function(name, scores) {
let max = Math.max(...scores);
return `Hello ${name}. Your max score is ${max}.`
},
"args": [ "$name", "$scores"],
"lang": "js"
}
}
}
}
]
}
}
""")
I'm new in Spring-Data-MongoDB, I'm developing a method that performs MongoDB $accumulator operator in Spring-Data-MongoDB, but I don't know why my result on the $accumulator field return null.
Now I'm populating the collection in MongoDB:
db.game.insertMany([
{ "_id" : 1, "name" : "John", "score" : 10},
{ "_id" : 2, "name" : "Elizabeth", "score" : 10},
{ "_id" : 3, "name" : "James ", "score" : 9},
{ "_id" : 4, "name" : "John", "score" : 5},
{ "_id" : 5, "name" : "Elizabeth", "score" : 10},
{ "_id" : 6, "name" : "John", "score" : 10},
{ "_id" : 7, "name" : "Elizabeth", "score" : 10},
{ "_id" : 8, "name" : "James ", "score" : 8 },
{ "_id" : 9, "name" : "James ", "score" : 8}])
This is the accumulator aggregation in MongoDB Server:
db.game.aggregate ([
{
$group :
{
_id : "$name",
avgScore:
{
$accumulator:
{
init: function() {
return { count: 0, sum: 0 }
},
accumulate: function(state, score) {
return {
count: state.count + 1,
sum: state.sum + score
}
},
accumulateArgs: ["$score"],
merge: function(state1, state2) {
return {
count: state1.count + state2.count,
sum: state1.sum + state2.sum
}
},
finalize: function(state) {
return (state.sum / state.count)
},
lang: "js"
}
}
}
}
])
This is the result of MongoDB that I'm trying to perform via Spring-Data-MongoDB:
{ "_id" : "Elizabeth", "avgScore" : 10 }
{ "_id" : "John", "avgScore" : 8.333333333333334 }
{ "_id" : "James ", "avgScore" : 8.333333333333334 }
This is the result of My RestController:
[
{
"name": "Elizabeth",
"avgScore": null
},
{
"name": "James ",
"avgScore": null
},
{
"name": "John",
"avgScore": null
}
]
this is the model Class
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection="game")
public class Game {
#Id
private Integer _id;
private String name;
private Integer score;
public Game() {
super();
// TODO Auto-generated constructor stub
}
public int get_id() {
return _id;
}
public void set_id(Integer _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
}
This is the Service that performs the $accumulator operator on accumulator method, but it returns null:
import java.util.LinkedList;
import java.util.List;
import com.project.ecommercemongo.aggregation.ResultAccumulator;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationExpression;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorAccumulateArgsBuilder;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorFinalizeBuilder;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorInitArgsBuilder;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorInitBuilder;
import org.springframework.data.mongodb.core.aggregation.ScriptOperators.Accumulator.AccumulatorMergeBuilder;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.group;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;
import org.springframework.stereotype.Service;
import org.springframework.data.mongodb.core.aggregation.GroupOperation;
import com.project.ecommercemongo.model.Game;
import com.project.ecommercemongo.repository.GameRepository;
#Service
public class GameService {
#Autowired
GameRepository game;
#Autowired
MongoTemplate mongoTemplate;
#Autowired
private MongoOperations mongoOperations;
public List<Game> findAll() {
List<Game> list = game.findAll();
return list;
}
public List<ResultAccumulator> accumulator() {
AccumulatorInitBuilder aib = ScriptOperators.accumulatorBuilder();
AccumulatorInitArgsBuilder aiab = aib.init("function() {return { count: 0, sum: 0 }}");
aib.lang("js");
AccumulatorAccumulateArgsBuilder aaac = aiab
.accumulate("function(state, score) { return {count: state.count + 1,sum: state.sum + score}}");
List<Object> bl = new LinkedList<Object>();
bl.add("score");
AccumulatorMergeBuilder amb = aaac.accumulateArgs(bl);
AccumulatorFinalizeBuilder afb = amb.merge(
"function(state1, state2) {return {count: state1.count + state2.count,sum: state1.sum + state2.sum}}");
// Accumulator a=afbb.build();
Accumulator a = afb.finalize("function(state) {return (state.sum / state.count)}");
Document document = a.toDocument();
/*AggregationExpression expression = new AggregationExpression() {
#Override
public Document toDocument(AggregationOperationContext context) {
Document document1 = document;
return document1;
}
};
Document document2 = expression.toDocument();*/
GroupOperation groupByNameAndAccumulator = group("name").last(String.valueOf(document)).as("avgScore");
Aggregation aggregation = newAggregation(groupByNameAndAccumulator);
List<ResultAccumulator> results = mongoOperations
.aggregate(aggregation, mongoTemplate.getCollectionName(Game.class), ResultAccumulator.class)
.getMappedResults();
// AggregationResults<ResultAccumulator> result =
// mongoTemplate.aggregate(aggregation, "game", ResultAccumulator.class);
System.out.println(document);
System.out.println(results.toString());
return results;
}
}
This is the server that print the Document containing the accumulator operator,
2022-07-04 00:42:28.696 INFO 13784 --- [nio-8080-exec-2] org.mongodb.driver.connection : Opened connection [connectionId{localValue:3, serverValue:1531}] to localhost:27118
Document{{$accumulator=Document{{init=function() {return { count: 0, sum: 0 }}, accumulate=function(state, score) { return {count: state.count + 1,sum: state.sum + score}}, accumulateArgs=[score], merge=function(state1, state2) {return {count: state1.count + state2.count,sum: state1.sum + state2.sum}}, lang=js, finalize=function(state) {return (state.sum / state.count)}}}}}
[com.project.mongo.aggregation.ResultAccumulator#37517d96, com.project.mongo.aggregation.ResultAccumulator#19e6b063, com.project.emongo.aggregation.ResultAccumulator#3d69a1a5]
this is the Result Class
import org.springframework.data.annotation.Id;
public class ResultAccumulator {
#Id
private String name;
private Double avgScore;
public ResultAccumulator() {
super();
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getAvgScore() {
return avgScore;
}
public void setAvgScore(Double avgScore) {
this.avgScore = avgScore;
}
}
this is the Controller
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.project.ecommercemongo.aggregation.ResultAccumulator;
import com.project.ecommercemongo.model.Game;
import com.project.ecommercemongo.service.GameService;
#RestController
#RequestMapping("/game")
public class GameController {
#Autowired
GameService service;
#GetMapping("/find")
public List<Game> listAll() {
return service.findAll();
}
#GetMapping("/accumulator")
public List<ResultAccumulator> accumulator() {
return service.accumulator();
}
}
I don't know what I'm doing wrong, maybe the problem is in the Object Accumulator .
Bye and thank you in advance!
Update
Now it work my mistake was on the method last in group,now i have changed to accumulate(Accumulator)
AccumulatorInitBuilder aib = ScriptOperators.accumulatorBuilder();
AccumulatorInitArgsBuilder aiab = aib.init("function() {return { count: 0, sum: 0 }}");
aib.lang("js");
AccumulatorAccumulateArgsBuilder aaab = aiab
.accumulate("function(state, score) { return {count: state.count + 1,sum: state.sum + score}}");
List<Object> bl = new LinkedList<Object>();
bl.add("$score");
AccumulatorMergeBuilder amb = aaab.accumulateArgs(bl);
AccumulatorFinalizeBuilder afb = amb.merge(
"function(state1, state2) {return {count: state1.count + state2.count,sum: state1.sum + state2.sum}}");
// Accumulator a=afbb.build();
Accumulator a = afb.finalize("function(state) {return (state.sum / state.count)}");
GroupOperation groupByNameAndAccumulator = group("name").accumulate(a).as("avgScore");
Aggregation aggregation = newAggregation(groupByNameAndAccumulator);
List<ResultAccumulator> results = mongoOperations
.aggregate(aggregation, mongoTemplate.getCollectionName(Game.class), ResultAccumulator.class)
.getMappedResults();
// AggregationResults<ResultAccumulator> result =
// mongoTemplate.aggregate(aggregation, "game", ResultAccumulator.class);
return results;
public class ResultAccumulator {
#Id
private String name;
private Float avgScore;
public ResultAccumulator() {
// TODO Auto-generated constructor stub
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Float getAvgScore() {
return avgScore;
}
public void setAvgScore(float avgScore) {
this.avgScore = avgScore;
}
}
[
{
"name": "Elizabeth",
"avgScore": 10.0
},
{
"name": "James ",
"avgScore": 8.333333
},
{
"name": "John",
"avgScore": 8.333333
}
]
I'm developing a spring boot application. I've 2 models that is
PersonEntity
#Data
#Document(collection = "products")
public class ProductEntity implements Serializable {
private static final long serialVersionUID = -8118791879505582652L;
#MongoId(FieldType.STRING)
private String id;
#Indexed
#Field("name")
private String name;
#Field("category")
#DBRef(lazy = true)
private CategoryEntity category;
// getters and setters
}
CategoryEntity
#Data
#Document(collection = "categories")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = -636356399519451958L;
#MongoId(value = FieldType.STRING)
private String id;
#Field("name")
private String name;
#Field("desc")
private String desc;
public CategoryEntity(String id) {
super();
this.id = id;
}
// getters and setters
}
when I'm saving data into DB then stored data is
Products Document
{
"_id": {
"$oid": "6141eeab92432109463ae8c4"
},
"name": "Adidas Running Shoes",
"category": {
"$ref": "categories",
"$id": "614049d91042cf40b5b9b304"
}
}
Categories Document
{
"_id": {
"$oid": "614049d91042cf40b5b9b304"
},
"name": "Shoes",
"desc": "Men's running Shoes",
}
But when I'm try to findAll() the ProductEntity the data by using Spring-Data-MongoDB the category will return null.
public List<ProductModel> getProducts() {
List<ProductEntity> entities = productRepo.findAll();
return entities.stream().map(entity -> {
ProductModel product = new ProductModel();
BeanUtils.copyProperties(entity, product);
if (Objects.nonNull(entity.getCategory())) {
BeanUtils.copyProperties(entity.getCategory(), product.getCategory());
}
return product;
}).collect(Collectors.toList());
}
and I need the output will be in below format.
{
"_id": {
"$oid": "6141eeab92432109463ae8c4"
},
"name": "Adidas Running Shoes",
"category": {
"_id": {
"$oid": "614049d91042cf40b5b9b304"
},
"name": "Shoes",
"desc": "Men's running Shoes",
}
}
Please let me know how to get desired output.
I've done a minor change and issue has been resolved. I've changed
from
#MongoId(value = FieldType.STRING)
private String id;
to
#MongoId(value = FieldType.OBJECT_ID)
private ObjectId id;
in the both entities and code works!
Iam new with drools. I created the following object:
package com.myspace.applicant;
public class Applicant implements java.io.Serializable {
static final long serialVersionUID = 1L;
private java.lang.Integer age;
private java.lang.Boolean approved;
private java.lang.Double money;
private java.lang.String name;
public Applicant() {
}
public java.lang.Integer getAge() {
return this.age;
}
public void setAge(java.lang.Integer age) {
this.age = age;
}
public java.lang.Boolean getApproved() {
return this.approved;
}
public void setApproved(java.lang.Boolean approved) {
this.approved = approved;
}
public java.lang.Double getMoney() {
return this.money;
}
public void setMoney(java.lang.Double money) {
this.money = money;
}
public java.lang.String getName() {
return this.name;
}
public void setName(java.lang.String name) {
this.name = name;
}
public Applicant(java.lang.Integer age, java.lang.Boolean approved,
java.lang.Double money, java.lang.String name) {
this.age = age;
this.approved = approved;
this.money = money;
this.name = name;
}
}
and a *.drl file which contains the rule:
package com.myspace.applicant;
import com.myspace.applicant.Applicant;
no-loop
rule "approve applicants"
when
$a: Applicant(age > 30, money > 1000, approved == false)
then
modify($a) {
setApproved(true);
}
end
In Postman I tried to call the rule with the following body:
{
"lookup" : null,
"commands" : [ {
"insert" : {
"objects" : {
"Applicant": {
"age": 28,
"approved": false,
"money": 10000,
"name": "boehlen"
}
},
"disconnected" : false,
"out-identifier": "Applicant",
"return-object" : true,
"entry-point" : "DEFAULT"
}
}, {
"fire-all-rules" : {}
} ]
}
I got the following answer:
{
"type" : "SUCCESS",
"msg" : "Container Applicant_1.0.0-SNAPSHOT successfully called.",
"result" : {
"execution-results" : {
"results" : [ {
"value" : null,
"key" : "Applicant"
} ],
"facts" : [ {
"value" : null,
"key" : "Applicant"
} ]
}
}
}
The problem is, that my value is null instead of the object I expect as a response. The server.log is empty and I do not see what is wrong. Please could you help me.
Thank you very much.
Your rule only triggers if the Applicant age is greater than 30. Your input value includes an age of 28.
I was able to solve the problem. It was a typo. Instead of "results" I had to write "result". Thanks a
This is City document class which i used.
#Document("city")
public class City {
#Id
private String id;
#Indexed(unique = true)
private String name;
#DBRef(lazy = true)
private District district;
public City() {
}
public City(String id) {
this.id = id;
}
public City(String id, String name, District district) {
this.id = id;
this.name = name;
this.district = district;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public District getDistrict() {
return district;
}
public void setDistrict(District district) {
this.district = district;
}
}
and this is the District document class
#Document("district")
public class District {
#Id
private String id;
#Indexed
private String name;
public District() {
}
public District(String id) {
this.id = id;
}
public District(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
and this is the district collection data.
/* 1 */
{
"_id" : ObjectId("5d9482f3ff7ab743f0542070"),
"name" : "Ampara",
"_class" : "com.test.sample.model.District"
}
/* 2 */
{
"_id" : ObjectId("5d9482f3ff7ab743f0542071"),
"name" : "Anuradhapura",
"_class" : "com.test.sample.model.District"
}
and this is the city collection data.
/* 1 */
{
"_id" : ObjectId("5d948333ff7ab743f0542089"),
"name" : "Polgampola",
"district" : {
"$ref" : "district",
"$id" : ObjectId("5d9482f3ff7ab743f0542070")
},
"_class" : "com.test.sample.model.City"
}
/* 2 */
{
"_id" : ObjectId("5d948333ff7ab743f054208a"),
"name" : "Porawagama",
"district" : {
"$ref" : "district",
"$id" : ObjectId("5d9482f3ff7ab743f0542070")
},
"_class" : "com.test.sample.model.City"
}
/* 3 */
{
"_id" : ObjectId("5d948333ff7ab743f054208b"),
"name" : "Akkaraipattu",
"district" : {
"$ref" : "district",
"$id" : ObjectId("5d9482f3ff7ab743f0542071")
},
"_class" : "com.test.sample.model.City"
}
this is the repository class for the above city document class
#Repository
public interface CityDao extends MongoRepository<City,String> {
List<City> findByDistrict(String id);
}
in the city class, i have used referenced document class called District. this a another document. I need to get the cities which belong to one district. findByDistrict(String id) method doesn't return values. Its just returning empty List. So How can i do this ?
I have tried with another alternative.As #pvpkirn said, You cannot query with #DBRef. But i tried with MongoOperations. With this we can pass the Filter objects as Json object. Using this i got the answer. This is what i tried.
public List<City> findByDistrictId(String districtId) {
final Bson filter = eq("district.$id", new ObjectId(districtId));
FindIterable<Document> documents = super.mongoOperations.getCollection("city").find(filter);
List<City> cities = new ArrayList<>();
for(Document document : documents){
City city = new City(document.getObjectId("_id").toString(),document.getString("name"),new District(districtId));
cities.add(city);
}
return cities;
}
in here i have used com.mongodb.client.model.Filters.eq to get the relevant bson object.