mongodb 聚合连表lookup查询子表_id 格式ObjectId是会被当成BSON解析的问题


sql语句Navicat控制台输出:(也是想要的结果)


db.user.aggregate([{ "$match" : {"userId":  NumberLong("4071" }} ,{$lookup: {
         from: 'tb_template',
         localField: 'userId',
         foreignField: 'userId',
         as: 'template'
}}])

以下是结果:


{
    "_id": ObjectId("62a8314584ea1"),
    "userId": NumberLong("4071"),
    "template": [
        {
            "_id": ObjectId("628f39c0b594df"),
            "userId": NumberLong("4071"),
            "visits": NumberInt("0"),
            "content": "",
            "status": NumberInt("0"),
            "hashMap": { },
            "list": [ ],
            "object": { }
        }
    ]
}

 

以下是java查询代码:

Aggregation agg = Aggregation.newAggregation(
       Aggregation.match(Criteria.where("userId").is(4071L)),
       Aggregation.lookup("tb_template","userId","userId","template")
);

java输出结果:template.id问题出现导致前端无法使用


{
    "_id": ObjectId("62a8314584ea1"),
    "userId": NumberLong("4071"),
    "template": [
        {
           "_id": {
                "timestamp": 1653551504,
                "counter": 11906057,
                "time": 1653551504000,
                "date": "2022-05-26T07:51:44.000+0000",
                "timeSecond": 1653551504,
                "processIdentifier": 18880,
                "machineIdentifier": 2697172
             },
            "userId": NumberLong("4071"),
            "visits": NumberInt("0"),
            "content": "",
            "status": NumberInt("0"),
            "hashMap": { },
            "list": [ ],
            "object": { }
        }
    ]
}

我想要达到的结果

理想结果是:template.id=628f39c0b594df 字符串二不是一个BSON格式,

请问大家都有什么解决方法,不在查询结果过for格式化或者转义情况下,使用mongodb自带方法最好

转换BSON类型ObjectId到JSON(存储在MongoDB)

最正确的方法可能是使用GSON TypeAdapter来配置ObjectId如何写入(和读取)JSON。您需要创建一些实现TypeAdapter的东西,并将其注册到GsonBuilder,这样GSON就知道有一种处理objectid的特殊方法。

private class ObjectIdTypeAdapter extends TypeAdapter<ObjectId> {
    @Override
    public void write(final JsonWriter out, final ObjectId value) throws IOException {
        out.beginObject()
           .name("$oid")
           .value(value.toString())
           .endObject();
    }

    @Override
    public ObjectId read(final JsonReader in) throws IOException {
        in.beginObject();
        assert "$oid".equals(in.nextName());
        String objectId = in.nextString();
        in.endObject();
        return new ObjectId(objectId);
    }
}

写的测试:

@Test
public void shouldWriteCorrectJSON() {
    // given
    TaskObject taskObject = new TaskObject();
    taskObject._id = new ObjectId("51eae100c2e6b6c222ec3431");

    Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).create();

    // when
    String gsonString = gson.toJson(taskObject);

    // then
    assertThat(gsonString, is("{\"_id\":{\"$oid\":\"51eae100c2e6b6c222ec3431\"}}"));
}

读的测试:

@Test
public void shouldReadFromJSON() {
    // given
    Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).create();

    // when
    TaskObject actualTaskObject = gson.fromJson("{\"_id\":{\"$oid\":\"51eae100c2e6b6c222ec3431\"}}", TaskObject.class);

    // then
    TaskObject taskObject = new TaskObject();
    taskObject._id = new ObjectId("51eae100c2e6b6c222ec3431");
    assertThat(actualTaskObject._id, is(taskObject._id));
}