Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 如何让Spring数据Mongo聚合像使用Mongo一样工作_Mongodb_Aggregation Framework_Spring Data Mongodb - Fatal编程技术网

Mongodb 如何让Spring数据Mongo聚合像使用Mongo一样工作

Mongodb 如何让Spring数据Mongo聚合像使用Mongo一样工作,mongodb,aggregation-framework,spring-data-mongodb,Mongodb,Aggregation Framework,Spring Data Mongodb,我正在尝试使用SpringDataMongo的聚合API进行一个简单的投影 我想做的管道步骤是: { $project : { "account._id" : 1, "account.position" : 1 } } 这是我尝试过的,还有很多其他的调整,因为似乎什么都不起作用: ProjectionOperation project1 = Aggregation.project("account._id", "account.position"); 然而,尽管文档中

我正在尝试使用SpringDataMongo的聚合API进行一个简单的投影

我想做的管道步骤是:

{
  $project : {
    "account._id" : 1,
    "account.position" : 1
  }
}
这是我尝试过的,还有很多其他的调整,因为似乎什么都不起作用:

ProjectionOperation project1 = Aggregation.project("account._id", "account.position");
然而,尽管文档中说要在这里实现这一点:

由该投影呈现的实际文档最终看起来像:

{
  $project : {
    _id : "$account._id",
    position : "$account.position"
  }
}
它的工作原理与我想要使用的投影完全不同

有人知道如何从SpringDataMongo聚合API中获得我想要的投影吗?或者这是我需要报告的一个bug吗

2019年8月29日更新-添加更多数据以构建上下文:

涉及两个集合:组和帐户 一个组看起来像这样:

{
  _id : ObjectId("..."),
  name: ..., 
  ownerId: ObjectId("..."),
  other stuff...
}
{
  _id : ObjectId("..."),
  position : "ABC",
   memberships : [{
    groupId: ObjectId("..."),
    otherstuff: ...,
  }],
  other stuff...
}
帐户的外观如下所示:

{
  _id : ObjectId("..."),
  name: ..., 
  ownerId: ObjectId("..."),
  other stuff...
}
{
  _id : ObjectId("..."),
  position : "ABC",
   memberships : [{
    groupId: ObjectId("..."),
    otherstuff: ...,
  }],
  other stuff...
}
我的整个聚合看起来是这样的,并且在mongodb shell中工作正常:尝试获取特定类型的所有帐户ID的列表,这些ID是特定用户拥有的任何组的成员

groups.aggregate(
    {
        $match : {
            ownerId : ObjectId("XYZ"),
        }
    },
    {
        $lookup: {
               from: "accounts",
               localField: "_id",
               foreignField: "memberships.groupId",
               as: "account"
             }
    },
    {
        $project: {
            "account._id" : 1,
            "account.position" : 1
        }
    },
    {
        $unwind: "$account"
    },
    {
        $match: {
            "account.position" : "ZZZ"
        }
    },
    {
        $project: {
            _id : 0,
            accountId : "$account._id"
        }
    })
聚合的Java版本:

MatchOperation match1 = Aggregation.match(
  where("ownerId").is(accountId));

LookupOperation lookupOperation = LookupOperation.newLookup()
  .from("accounts")
  .localField("_id")
  .foreignField("memberships.groupId")
  .as("account");

// This doesn't work correctly on nested fields:
ProjectionOperation project1 = Aggregation.project(
  "studentAccount._id", 
  "studentAccount.position");

Aggregation aggregation = Aggregation.newAggregation(
  match1,
  lookupOperation,
  project1,  
  unwind("account"),
  match(where("account.position").is("ZZZ")),
  project().and("account._id").as("accountId"));

如果您想让聚合工作看起来像mongoshell,您可以这样尝试

Aggregation aggregation = Aggregation.newAggregation(
                match1,
                lookupOperation,
                // This's your project operation
                 new AggregationOperation() {
                    @Override
                    public Document toDocument(AggregationOperationContext aggregationOperationContext) {
                        Document project = new Document("$project",
                                new Document(
                                        "_id", "$account._id"
                                ).append("position", "$account.position")
                        );
                        return aggregationOperationContext.getMappedObject(project);
                    }
                },
                unwind("account"),
                match(where("account.position").is("ZZZ")),
                project().and("account._id").as("accountId")
        );


您可以用更通用的方式检查我的答案

您是否可以共享所涉及的域类型以及整个聚合,而不仅仅是一个项目操作。在类型化聚合的情况下,属性映射到字段名。@christofstrobl,我在问题中添加了其他信息。是的,我知道我可以这样做。我考虑将整个聚合编写为json,因为这就是我开发管道并解析它以运行的方式,但我正在尝试通过SpringAggregationAPI解决这个问题。