Mongodb _id 在同一个集合中有两种不同的数据类型

Posted

技术标签:

【中文标题】Mongodb _id 在同一个集合中有两种不同的数据类型【英文标题】:Mongodb _id has two different datatypes in same collection 【发布时间】:2020-12-03 06:24:34 【问题描述】:

我正在从事的项目使用 mongodb 作为数据库,并有一个模拟数据生成器。 当通过模拟数据生成器生成数据时,它会在数据库中创建带有字符串 ID 的对象。 而我们的后端应用程序 Spring boot 使用 spring data mongodb 存储新对象,_id 为 ObjectId


    "_id" : ObjectId("6163686f6c64722d30303031"),
    "email" : "Price36@hotmail.com",
    "modeOfContact" : "EMAIL",
    "name" : "Leonardo Walter",
    "phone" : "08802273531"



    "_id" : "customer-1",
    "email" : "Casimer_Jakubowski@hotmail.com",
    "modeOfContact" : "EMAIL",
    "name" : "Kennedy Kilback",
    "phone" : "07624333004"

现在我们有一个基于节点的应用程序,仅用于获取调用,它使用“mongodb”包来解析查询。

当我对带有 String _id 的对象进行以下查询时,它可以工作

findDocument(COLLECTION_NAME,  _id: args.id)

但是当对象的 _id 为 ObjectId 时查询失败

有没有一种方法可以通过提供 _id 和数据类型来搜索对象 喜欢

findDocument(COLLECTION_NAME,   _id: args.id , $type: [ 'string', 'ObjectId'])

我知道 $type 会返回所有 _id 与该类型匹配的记录。只是想解释一下我想在这里实现什么。

【问题讨论】:

【参考方案1】:

但是当对象的 _id 为 ObjectId 时查询失败

要从 nodejs 中查询 mongo 中的 ObjectId,您需要创建一个 ObjectId:

var ObjectID = require('mongodb').ObjectID;

// Create a new ObjectID (hex string is 24 characters long)
var objectId = new ObjectID('6163686f6c64722d30303031');

// NOTE: you try to run `new ObjectID('customer-1');` you will get an Exception

findDocument(COLLECTION_NAME,  _id: objectId)

我认为更好的方法是更新您的模拟以插入有效的 ObjectID 而不是字符串,如果这对您无关紧要,因为您需要保证 _id 的唯一性

【讨论】:

感谢@Manuel 的回复,但有时我会从前端获取 _id 作为字符串,有时是 ObjectId。我试过你的解决方案,当来自前端的 _id 是十六进制字符串时它会起作用,否则它会抛出异常。 我还尝试通过模拟数据添加 ObjectId,在某些集合中我引用了某些对象中的对象。在这种情况下,在我的 java 端,只有当我使用 _id 字段查询时,即 _id 是 ObjectId 并且当我在对象中使用引用请求时,我才会得到结果。` SomeEntity findById(String id)` 返回预期结果,因为 _id ObjectId 但SomeEntity findByReferenceId(String refId) 返回 null 结果,因为 ReferenceId 只是十六进制字符串 如果您有混合格式,您可以在创建新 ObjectID 时添加 trycatch 是的,目前看来这似乎是一个快速解决方案【参考方案2】:

当对象的 _id 为 ObjectId 时查询失败

解决此问题的一种方法是仅在有效的ObjectId 使用ObjectID.isValid() 时使用ObjectID 构造

const mongodb = require("mongodb").ObjectID;

const validId = mongodb.ObjectID.isValid(args._id);
/*only convert to ObjectID if validId true*/
const idToQuery = validId ? new mongodb.ObjectID(args._id) : args._id;

findDocument(COLLECTION_NAME,  _id: idToQuery );

【讨论】:

以上是关于Mongodb _id 在同一个集合中有两种不同的数据类型的主要内容,如果未能解决你的问题,请参考以下文章

自定义 MongoDB 对象 _id 与复合索引

子文档 MongoDB 中键的不同值(1 亿条记录)

MongoDB 数据库引用

如何使用python在mongodb的两种不同类型的字段或索引或标题中搜索值?

如何编组/解组在 Go 中有两种不同格式的通用 JSON 和 BSON 键/字段?

MongoDB - 查询大型集合