ref
私はからなるコレクションを持っています
{
"_id": "refId"
"ref": "itemId"
}
そしてコレクションitem
{
"_id": "itemId"
"field1": ...
"array": [
{
"field2": "a"
},
{
"field2": "b"
}
]
}
ここで、「結合」する必要があります。別名lookup
on ref
to を実行しitem
、フィールドとasfield1
の最後の項目をリターン ドキュメントのトップ レベルに射影して、返す必要があります。array
arrayItem
{
"_id": "itemId",
"field1": ...
"arrayItem: "b"
}
mongo シェルを使用すると、これは次のステートメントを使用して完全に機能します。
db.ref.aggregate([
{ "$lookup": {
"from": "item",
"localField": "ref",
"foreignField": "_id",
"as": "item"
}},
{ "$unwind": "$item" },
{ "$project": {
"_id": "$item._id",
"field1": "$item.field1",
"arrayItem": { $slice: [ "$item.array", -1, 1 ]}
}},
{ "$unwind": "$arrayItem" }
])
今、私はこれをJavaでSpringとSpring-MongoDBで実現する必要があります。これは、この集約を使用してみました:
Aggregation.newAggregation(
new LookupAggreationOperation("item", "ref", "_id", "item"),
Aggregation.unwind("item"),
Aggregation.project(Fields.from(
Fields.field("_id", "$item._id"),
Fields.field("field1", "$item.field1"),
Fields.field("array", "$item.array"))),
Aggregation.project("_id", "field1", "array")
.and("$array").project("slice", -1, 1).as("$arrayItem"),
Aggregation.unwind("$array"));
ルックアップは Spring-Mongo 1.9.2 でのみ利用できるため、次のように自分で再構築する必要がありました。
public class LookupAggregationOperation implements AggregationOperation {
private DBObject operation;
public LookupAggregationOperation(String from, String localField,
String foreignField, String as) {
this.operation = new BasicDBObject("$lookup", //
new BasicDBObject("from", from) //
.append("localField", localField) //
.append("foreignField", foreignField) //
.append("as", as));
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
問題は、スライス コマンドがまだ集約のメソッドとして実装されていない (そして 1.9.2 に実装されていない) ため、 DATAMONGO-1457project("slice", -1, 1).as("$arrayItem")
で提案されているように呼び出す必要があることです。スライスは単に実行されず、結果は null です。arrayItem
Spring MongoDB 1.8.4 および MongoDB 3.2.8 で Spring 1.3.5 を使用しています。