将聚合中的 `_id`(ObjectId)转换为字符串以在Spring Boot的lookup中使用。

huangapple go评论59阅读模式
英文:

convert _id(ObjectId) to String in aggregation for lookup Spring boot

问题

我曾经长时间面临一个问题,就是在Spring Boot聚合中将objectId转换为字符串,而我找不到任何有用的方法来解决它。最终,我找到了解决方法,并愿意与那些有相同问题的人分享我的方法;
正如你所知道的,lookup需要两边的查找具有相同值,例如,两边都是objectId或两边都是字符串。
如果你一边有objectId,另一边有字符串,你需要将这个objectId转换为字符串,然后编写你的lookup阶段;
在lookup之前的阶段应该是使用$toString表达式的投影阶段,像下面这样:
```java
ProjectionOperation projectionOperation = Aggregation.project(/*你需要的字段 */)
.and(ConvertOperators.ToString.toString("$_id")).as("aggId");

然后你可以像下面这样轻松使用lookup:

Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(
                        Criteria.where("creatorId").is(userId)
                )
                ,
                projectionOperation
                ,
                Aggregation.lookup("post", "aggId", "courseId", "postList"),

我的完整聚合代码如下:

ProjectionOperation projectionOperation = Aggregation.project(/*你需要的字段 */)
.and(ConvertOperators.ToString.toString("$_id")).as("aggId");

Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(
                        Criteria.where("creatorId").is(userId)
                )
                ,
                projectionOperation
                ,
                Aggregation.lookup("post", "aggId", "courseId", "postList")
);

return this.aggregate(agg, entityClass, Object.class).getMappedResults();

希望这对你有帮助。


<details>
<summary>英文:</summary>

**THIS IS NOT QUESTION**

I had a problem for a long time to convert objectId to string in spring boot aggregation and I can&#39;t find any useful way to solve it.
finally, I figure out and I like to share my way to those who have the same problem;
As you know lookup need two sides of lookup the same value, for example, two sides objectId or two sides string
if you have objecteId and string in another side you have to make this objectId to string and then write your lookup stage;
the stage before lookup should be the project stage with usage of $toString expression like bellow:

ProjectionOperation projectionOperation = Aggregation.project(/*your nedded fields */)
.and(ConvertOperators.ToString.toString("$_id)).as("aggId");


and then you can use lookup easily like below:

Aggregation agg = Aggregation.newAggregation(
Aggregation.match(
Criteria.where("cratorId").is(userId)
)
,
projectionOperation
,
Aggregation.lookup("post", "aggId", "courseId", "postList"),

my full aggregation is:

ProjectionOperation projectionOperation = Aggregation.project(/*your nedded fields */)
.and(ConvertOperators.ToString.toString("$_id")).as("aggId");

Aggregation agg = Aggregation.newAggregation(
Aggregation.match(
Criteria.where("creatorId").is(userId)
)
,
projectionOperation
,
Aggregation.lookup("post", "aggId", "courseId", "postList")
);

return this.aggregate(agg, entityClass, Object.class).getMappedResults();


hope it can be useful

</details>


# 答案1
**得分**: 1

我也在研究这个问题的答案,我找到了这个解决方案。

我正在使用 `spring-data-mongodb:3.0.0.RELESE`。

在您的聚合管道中:
```Kotlin
AddFieldsOperation.builder().addField("strId")
                    .withValue(
                        ConvertOperators.ToString.toString("$_id")
                    ).build()

这相当于

{
    $addFields: {
        strId: {$toString: "$_id"}
    }
}

您可以将 strId 替换为任何您想要的名称,并在接下来的操作中使用它。

英文:

I was looking into the answer to this question also and I found this solution.

I am using spring-data-mongodb:3.0.0.RELESE.

In your aggregation pipeline

AddFieldsOperation.builder().addField(&quot;strId&quot;)
                    .withValue(
                        ConvertOperators.ToString.toString(&quot;$_id&quot;)
                    ).build()

This is the equivalent to

{
    $addFields: {
        strId: {$toString: &quot;$_id&quot;}
    }
}

You can replace strId with any name you want and use it in the next operation.

答案2

得分: 1

List<Map> getMultiTable(){
    ProjectionOperation projectionOperation = Aggregation.project(/*你所需的字段*/)
            .and(ConvertOperators.ToString.toString("$_id")).as("_id")
            .and(ConvertOperators.ToObjectId.toObjectId("$userId")).as("userId");

    Aggregation agg = Aggregation.newAggregation(
            Aggregation.match(
                    Criteria.where("status").is(0)
            ),
            projectionOperation,
            Aggregation.lookup("videoComment", "_id", "videoId", "commentList"),
            Aggregation.lookup("user", "userId", "_id", "userList")
    );

    List<Map> result = mongoTemplate.aggregate(agg, "mediaFile", Map.class).getMappedResults();
    System.out.println(result);
    return result;
}
英文:
List&lt;Map&gt; getMultiTable(){
    ProjectionOperation projectionOperation = Aggregation.project(/*your nedded fields */)
            .and(ConvertOperators.ToString.toString(&quot;$_id&quot;)).as(&quot;_id&quot;)
            .and(ConvertOperators.ToObjectId.toObjectId(&quot;$userId&quot;)).as(&quot;userId&quot;);

    Aggregation agg = Aggregation.newAggregation(
            Aggregation.match(
                    Criteria.where(&quot;status&quot;).is(0)
            ),
            projectionOperation,
            Aggregation.lookup(&quot;videoComment&quot;, &quot;_id&quot;, &quot;videoId&quot;, &quot;commentList&quot;),
            Aggregation.lookup(&quot;user&quot;, &quot;userId&quot;, &quot;_id&quot;, &quot;userList&quot;)
    );

    List&lt;Map&gt; result = mongoTemplate.aggregate(agg, &quot;mediaFile&quot;, Map.class).getMappedResults();
    System.out.println(result);
    return result;
}

huangapple
  • 本文由 发表于 2020年9月27日 14:56:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/64085730.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定