web-dev-qa-db-ja.com

春のデータmongoのMongodb $ lookup

私は新しいMongodbであり、$ lookup with Java springに問題があります。

このシェルをSpringデータで使用したい

db.NewFeed.aggregate([
    {
        $match : {username : "user001"}
    },
    {
      $lookup:
        {
          from: "NewfeedContent",
          localField: "content.contentId",
          foreignField: "_id",
          as: "NewfeedContent"
        }
   }
])

Googleで見つけましたが、まだ答えがありません。

7
Anh Bui

すべての「新しい」機能が、 spring-mongo などの抽象化レイヤーにすぐに組み込まれるわけではありません。

したがって、代わりに、AggregationOperationインターフェイスを使用するクラスを定義するだけで、代わりに、コンテンツとして直接指定されたBSONオブジェクトを取得します。

_public class CustomAggregationOperation implements AggregationOperation {
    private DBObject operation;

    public CustomAggregationOperation (DBObject operation) {
        this.operation = operation;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}
_

次に、次のように集計で使用できます。

_Aggregation aggregation = newAggregation(
    match(
        Criteria.where("username").is("user001")
    ),
    new CustomAggregationOperation(
        new BasicDBObject(
            "$lookup",
            new BasicDBObject("from", "NewFeedContent")
                .append("localField","content.contentId")
                .append("foreignField", "_id")
                .append("as", "NewFeedContent")
        )
    )
)
_

これは、組み込みのmatch()パイプラインヘルパーと混合されたカスタムクラスを示しています。

各ヘルパーの下で発生するのは、とにかくDBObjectなどのBSON表現にシリアル化することだけです。したがって、ここのコンストラクターはオブジェクトを直接取得し、それを.toDBObject()から直接返します。これは、piplineコンテンツをシリアル化するときに呼び出されるインターフェイスの標準メソッドです。

9
Blakes Seven

SpringDataで2つのコレクションを結合するMongoDB

従業員クラス

class Employee {
    private String _id;
    private String name;
    private String dept_id;
}

学科クラス

class Department {
    private String _id;
    private String dept_name;
}

従業員結果クラス

public class EmpDeptResult {

    private String _id;
    private String name;
    private List<Object> departments;
}

EmployeeServiceクラス

public class EmployeeService {

    @Autowired
    private MongoTemplate mongoTemplate;

    private Logger LOGGER = LoggerFactory.getLogger(EmployeeService.class);

    public void lookupOperation(){
    LookupOperation lookupOperation = LookupOperation.newLookup()
                        .from("Department")
                        .localField("dept_id")
                        .foreignField("_id")
                        .as("departments");

    Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("_id").is("1")) , lookupOperation);
        List<EmpDeptResult> results = mongoTemplate.aggregate(aggregation, "Employee", EmpDeptResult.class).getMappedResults();
        LOGGER.info("Obj Size " +results.size());
    }
}
11
Dhiren Chauhan

これに答えるには遅すぎますが、同じ問題に直面している他の人を助けるかもしれません。 spring-boot-data-mongodb-2.0以降のバージョンを使用している場合は、これを実装する簡単な方法があります。

AggregationOperation match = Aggregation.match(Criteria.where("username").is("user001")));
AggregationOperation query = Aggregation.lookup("NewfeedContent", "content.contentId", "_id", "NewfeedContent");
// If you want to unwind
//AggregationOperation unwind = Aggregation.unwind("Patient");
Aggregation agr = Aggregation.newAggregation(query, match, unwind);
AggregationResults<Document> result = springTemplate.aggregate(agr, "CollectionName", Document.class);
3
Vivek Singh

次に例を示します。

コレクション投稿

{
"_id" : ObjectId("5a198074ed31adaf5d79fe8a"),
"title" : "Post 1",
"authors" : [1, 2]
},
{
"_id" : ObjectId("5a198074ed31adaf5d79fe8d"),
"title" : "Post 2",
"authors" : [2]
}

コレクションユーザー

{
"_id" : ObjectId("5a18b483ed31ada08fd6ed82"),
"userId" : 1,
"name" : "Vinod Kumar"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed83"),
"userId" : 2,
"name" : "Jim Hazel"
},
{
"_id" : ObjectId("5a18b483ed31ada08fd6ed84"),
"userId" : 3,
"name" : "Alex Wong"
}

ルックアップと一致を使用したMongodbクエリ

db.users.aggregate([
{
  $lookup:
    {
      from: "users",
      localField: "userid",
      foreignField: "authors",
      as: "post"
    }
  },
  {
     $match: { "post": { $ne: [] } }
  }
]).pretty()

SpringMongoopration構文

LookupOperation lookupOperation = LookupOperation.newLookup().
            from("posts").
            localField("userid").
            foreignField("authors").
            as("post");

AggregationOperation match = Aggregation.match(Criteria.where("post").size(1));


Aggregation aggregation = Aggregation.newAggregation(lookupOperation, match);

List<BasicDBObject> results = mongoOperation.aggregate(aggregation, "users", BasicDBObject.class).getMappedResults();
3
VK321

以下を使用して3つのコレクションに参加できます

MongoClient mongoClient = new MongoClient( "localhost" , 27017 );

DB db = mongoClient.getDB( "DBname" );

BasicDBObject query = BasicDBObject.parse("{$match:{_id:61188}},\n" +
        "   {\n" +
        "     $lookup:\n" +
        "       {\n" +
        "         from: \"CustomerDetails\",\n" +
        "         localField: \"supplierId\",\n" +
        "         foreignField: \"supplierId\",\n" +
        "         as: \"newfield\"\n" +
        "       }\n" +
        "  }\n" +
        "  ,  {\n" +
        "     $lookup:\n" +
        "       {\n" +
        "         from: \"ItemDetails\",\n" +
        "         localField: \"supplierId\",\n" +
        "         foreignField: \"supplierId\",\n" +
        "         as: \"newfield\"\n" +
        "       }\n" +
        "  }");

AggregationOutput dumps = db.getCollection("HeaderInfo").aggregate(query);

System.out.println("result="+dumps.results());
0
vinay jain