mongodb 如何防止ObjectId转换为$oid:C# MongoDriver中的字符串格式

wdebmtf2  于 2023-08-04  发布在  Go
关注(0)|答案(1)|浏览(107)

我试图将Bson Document从我的dotnet程序发送到MongoDB,其中我有一个OBjectIds列表。问题是,在将文档插入MongoDB后,此列表会发生变化。
我正在尝试这个格式:

[
    {
        "_id" : ObjectId("<id1>")
        
    },
    {
        "_id" :  ObjectId("<id2>")
        
    },
    {
        "_id" :  ObjectId("<Id3>")
        
    }
]

字符串
在发送文件之前似乎是这样。然而,在插入Bson文档后,我收到了以下格式:

[
    {
        "_id" : {
            "$oid" : "<id1>"
        }
    },
    {
        "_id" : {
            "$oid" : "<id2>"
        }
    },
    {
        "_id" : {
            "$oid" : "<id3>"
        }
    }
]


下面是我如何初始化BsonArray if Ids:

public BsonArray GetSimilarDocumentsIds()
        {
            // similarIds is List<string> of ids
            var keys = similarIds.Keys.ConvertAll(x => new New BsonDocument("_id", new ObjectId(x)));
            var result = new BsonArray();
            foreach (var id in keys)
            {
                result.Add(id.ToBsonDocument());
            }
            return result;
        }

//-- somewhere later in the program

mainDocument.Add("SimilarIds", GetSimilarDocumentsIds())

await db.InsertOneAsync(mainDocument);


我试图覆盖BsonRepresentation,但它不起作用。将它 Package 在任何对象下都不起作用,而且我试图构建一个自定义的序列化程序,但没有工作。
我知道这是因为MongoDB扩展了JSON,但我必须修复它,因为它破坏了我们的约定格式。

hs1ihplo

hs1ihplo1#

即使有了额外的评论,我仍然不清楚这个问题和问题。具体来说,让我们关注这一点:
我尝试在数据库中以ObjectIds的表示形式写入它,并避免使用'$oid'表示形式。
MongoDB以类似JSON的格式存储信息,但它不直接使用JSON。它使用BSON。您可以在博客文章中找到有关BSON的更多信息,如Explaining BSON with ExamplesJSON and BSON。BSON有一个定义良好的结构,我们可以看到from its specification,一个字段的ObjectId的存储有以下具体表示:

"\x07" e_name (byte*12)

字符串
对于我们的目的,这些实现细节中的大多数都不重要。相关的事情是ObjectId的 * 内部表示 * 不与"$oid"这样的字符串相关联。正如您正确指出的,$oid命名法与 output format 相关联,该格式用于在JSON中表示BSON,同时保留类型信息。
我们可以运行一个快速练习来帮助确认这些说法。考虑以下情况:

> db.foo.find()
[
  { _id: 0, x: ObjectId("64c435faef01c4ed427ebead") },
  { _id: 1, x: { '$oid': '64c435faef01c4ed427ebead' } }
]
>
> db.foo.find({x: ObjectId("64c435faef01c4ed427ebead")})
[ 
  { _id: 0, x: ObjectId("64c435faef01c4ed427ebead") } 
]
>


这里我们在数据库中有两个文档,但实际上只有其中一个在其x字段中存储了ObjectId。当搜索 predicate 包含ObjectId时,只返回一个文档,这一事实证明了这一点。此外,我们可以进一步测试这一点,证明当这两个文档存在时,可以成功创建unique索引,但不能插入包含任何值的其他文档:

> db.foo.createIndex({x:1}, {unique: true})
x_1
>
> db.foo.insert({x: ObjectId("64c435faef01c4ed427ebead") })
Uncaught:
MongoBulkWriteError: E11000 duplicate key error collection: test.foo index: x_1 dup key: { x: ObjectId('64c435faef01c4ed427ebead') }
...
>
> db.foo.insert({  x: { '$oid': '64c435faef01c4ed427ebead' } })
Uncaught:
MongoBulkWriteError: E11000 duplicate key error collection: test.foo index: x_1 dup key: { x: { $oid: "64c435faef01c4ed427ebead" } }
...


只有当我们试图直接用JSON表示这两个文档时(通过前面提到的EJSON格式),这两个文档才会被类似地序列化(并且,可能具有讽刺意味的是,模棱两可):

>EJSON.stringify(db.foo.find().toArray())
[
    {"_id":0,"x":{"$oid":"64c435faef01c4ed427ebead"}},
    {"_id":1,"x":{"$oid":"64c435faef01c4ed427ebead"}}
]


总而言之,您的代码似乎成功地将信息存储为ObjectIds,而不是包含"$oid"字符串。只有当这些文档被序列化为JSON表示以在某些客户端shell/应用程序中显示时,您才能观察到它们。

相关问题