4

ref私はからなるコレクションを持っています

{
  "_id": "refId"
  "ref": "itemId"
}

そしてコレクションitem

{
  "_id": "itemId"
  "field1": ...
  "array": [
    {
      "field2": "a"
    }, 
    {
      "field2": "b"
    }
  ]
}

ここで、「結合」する必要があります。別名lookupon refto を実行しitem、フィールドとasfield1の最後の項目をリターン ドキュメントのトップ レベルに射影して、返す必要があります。arrayarrayItem

{
  "_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 を使用しています。

4

0 に答える 0