大猪oops 2022-06-16 00:11 采纳率: 0%
浏览 62
已结题

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自带方法最好

  • 写回答

1条回答 默认 最新

  • 笑看风云路 领域专家: 大数据技术领域 2022-06-22 20:14
    关注

    转换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));
    }
    
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月23日
  • 赞助了问题酬金5元 6月16日
  • 创建了问题 6月16日