집계 직접 MongoDB의 봄 데이터 클래스를 사용하지 않도록하고 사용되는 내 간단한 대답이 표준 MongoDB의 자바 예를 들어, 객체 DBObject/AggregationOutput
. 그 이유는 몇 시간 동안 MongoDB Spring 데이터에서 작동하는 기본적인 집계 쿼리를 얻으려고 몇 시간을 보냈다는 것입니다. 그리고 그 중 최신 데이터는 스프링 데이터 mongodb 1.5.0.RELEASE입니다.
그러나 표준 MongoDB Java 객체를 사용하여 집계 쿼리를 구성하는 것은 고통 스러울 수 있습니다 (특히 중첩/복합체 인 경우). DBObject groupFields = new BasicDBObject("_id", null);
이 무수하게 생성되고 코드가 엉망으로 보입니다.
코드에 다음과 같은 3 가지 래퍼 메서드를 추가하는 것이 좋습니다.
protected DBObject dbObj (String key, Object value) {
return new BasicDBObject (key, value);
}
protected DBObject dbObj (Object ... objs) {
DBObject dbObj = new BasicDBObject();
if (objs.length % 2 == 0) {
for (int i = 0; i < objs.length; i+=2) {
dbObj.put((String)objs[i], objs[i+1]);
}
}
return dbObj;
}
protected DBObject dbList (Object ... objs) {
BasicDBList dbList = new BasicDBList();
for (Object obj : objs) {
dbList.add(obj);
}
return (DBObject)dbList;
}
이렇게하면 JSON 기반 쿼리와 Java 코드를 쉽게 변환 할 수 있습니다. 예 : 당신이 (http://docs.mongodb.org/manual/tutorial/aggregation-zip-code-data-set/에서 가져온) 다음과 같은 복잡한 쿼리
db.zipcodes.aggregate(
{
$group: {
_id: { state: "$state", city: "$city" },
pop: { $sum: "$pop" }
}
},{
$sort: { pop: 1 }
},{
$group: {
_id: "$_id.state",
biggestCity: { $last: "$_id.city" },
biggestPop: { $last: "$pop" },
smallestCity: { $first: "$_id.city" },
smallestPop: { $first: "$pop" }
}
},{
$project: {
_id: 0,
state: "$_id",
biggestCity: {
name: "$biggestCity",
pop: "$biggestPop"
},
smallestCity: {
name: "$smallestCity",
pop: "$smallestPop"
}
}
});
이 있다면 그것이 작동하는 경우 ... 다음 Java 코드는 이런 식으로 이렇게 같은 것을 ...
List<DBObject> aggregation = Arrays.asList (
dbObj ("$group", dbObj (
"_id", dbObj ("state", "$state", "city", "$city"),
"pop", dbObj ("$sum", "$post")
)),
dbObj ("$sort", dbObj ("pop", 1)),
dbObj ("$group", dbObj (
"_id", "$_id.state",
"biggestCity", dbObj ("$last", "$_id.city"),
"biggestPop", dbObj ("$last", "$pop"),
"smallestCity", dbObj ("$first", "$_id.city"),
"smallestPop", dbObj ("$first", "$pop")
)),
dbObj ("$project", dbObj (
"_id", 0,
"state", "$_id",
"biggestCity", dbObj ("name", "$biggestCity", "pop", "$biggestPop"),
"smallestCity", dbObj ("name", "$smallestCity", "pop", "$smallestPop")
))
);
// Run aggregation query
DBCollection collection = mongoTemplate.getCollection(COLLECTION_NAME);
AggregationOutput output = collection.aggregate (aggregation);
을 보일 것이다 수동 그러나
List<MyResultClass> results = new ArrayList<MyResultClass>();
Iterator<DBObject> it = output.results().iterator();
while (it.hasNext()) {
DBObject obj = it.next();
MyResultClass result = mongoTemplate.getConverter().read(MyResultClass.class, obj);
results.add(result);
}
즉, 너무 고통스러운하지 않은 결과에서 개체를 변환해야합니다 있지만 편집기 (예 : RoboMongo은)는 자바 코드에서 작동합니다, 당신은 찾을 수 있습니다 Spring Data Aggregation은 잘 작동합니다. Spring을 좋아하고 Mongo Spring Data를 코드의 여러 부분에서 사용합니다. 여러 항목이있는 "$ 그룹"에서 "$ push"를 수행하면 작동하지 않는 것 같습니다. 시간이 갈수록 향상 될 것이라고 확신합니다. 다른 사람들이 이러한 생각을 반복합니다. http://movingfulcrum.tumblr.com/post/61693014502/spring-data-and-mongodb-a-mismatch-made-in-hell - 섹션 4 참조.
해피 코딩!
"유형"필드의 유형은 무엇입니까? – evanchooly
.count()를 주석 처리하기 전에 어떤 일이 발생 했습니까? btw, 무슨 몽고범 버전인가요? –
유형은 문자열입니다. 동일한 오류, y 의견은 최종 모델에 카운트가 있기 때문에 발생하지만 결과는 동일합니다. Mongo 버전 : 2.4.8 –