如何使用 Spring Data 从 MongoDB 文档中包含的数组中选择单个元素?

问题描述 投票:0回答:1

我是 MongoDB 新手。我有一个类似的集合:

[
   {
      "_id":"1",
      "travels":[
         {
            "_id":"1"
         },
         {
            "_id":"2"
         },
         {
            "_id":"3"
         }
      ]
   },
   {
      "_id":"2",
      "travels":[
         {
            "_id":"4"
         },
         {
            "_id":"5"
         },
         {
            "_id":"6"
         }
      ]
   }
]

我的 Java 模型或多或少是这样的(为了简单起见,使用公共修饰符):

public class TravelsDocument<T> {
    @Id
    public String id;
    public List<Travel> travels;
}
public class Travel {
    public String id;
}

travels 数组中的所有 id 都是唯一的。在我的 Spring 应用程序中,我想选择与指定 id 匹配的单个

travel
元素。

我终于弄清楚如何在 MongoDB 中做到这一点。 首先,我应用了过滤器:

{travels: {$elemMatch: { _id: 'someId'}}}

然后是投影:

{
   "_id":0,
   "travel":{
      "$arrayElemAt":[
         "$travels",
         {
            "$indexOfArray":[
               "$travels._id",
               "someId"
            ]
         }
      ]
   }
}

然后我尝试在聚合中使用它:

@Aggregation(pipeline = {
        "{'$match' :{'travels': {$elemMatch: { _id: :#{#id}}}}}",
        "{'$project' :{_id:0,     'travel':{$arrayElemAt: [ '$travels', {$indexOfArray :['$travels._id', :#{#id}]} ] }}}"})
    Mono<Travel> findSingleTravelByTenantAndId(@Param("id") String id);

问题是这个方法不返回我的

Travel
对象,而是返回
org.bson.Document
对象。有没有办法使用聚合注释返回我的自定义对象?这是要走的路吗?

java mongodb spring-data
1个回答
0
投票

聚合管道的最终投影阶段将返回文档为

{ travel: { _id: 123 } }
- 请注意外部
travel
字段。但这不是您的
Travel
类的结构,它只定义
id
(我认为映射到
_id
),可能还有其他字段/成员。

所以你需要添加一个

$replaceWith
阶段:

{ $replaceWith: "$travel" }

或者更好的是,删除项目阶段并使用replaceWith代替

{
  $replaceWith: {
      "$arrayElemAt":[
         "$travels",
         {
            "$indexOfArray":[
               "$travels._id",
               "someId"
            ]
         }
      ]
   }
}

所以完整的管道将是:

db.collection.aggregate([
  {
    $match: {
      travels: { $elemMatch: { _id: "someId" } }
    }
  },
  {
    $replaceWith: {
      $arrayElemAt: [
        "$travels",
        { $indexOfArray: ["$travels._id", "someId"] }
      ]
    }
  }
])

蒙戈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.