web-dev-qa-db-ja.com

マングース:ObjectIdの比較が一貫して失敗する

ドキュメントのコレクションを作成し、ExpressJS上に記述されたEPUBまたはLaTeXレンダリング用に自動的にフォーマットするための簡単なツールがあります。それが重要な場合、私はCoffeescriptを使用しています(私はそれを疑っています)。

マングースを使用して、私は以下を持っています:

DocumentSchema = new Schema
    title:     String

Offrefs = new Schema
    ref:       { type: ObjectId }
    isa:       String

BinderSchema = new Schema
    title:     String
    contains:  [Offrefs]

論理コレクションを作成するために、他のバインダーにいくつかのバインダーを含めることができるようにしたいので、Offrefsはそれが何を参照するかを指定しません:「これらはプリンター用です」「これらはepub用です」「これらはWeb専用です。 "など(私は雑多なものをすべて取り除いた。)

残念ながら、取得したオブジェクトのクエリに遭遇しました

(story._id == offref.ref) -> True 

そして、2つは確かに同じように見えます。だが:

(binder._id == offref.ref) -> False
(String(binder._id) == String(offref.ref)) -> True

そして、最後の2つの2つの参照を視覚的に比較すると、それらはare同じID番号ですが、ObjectIdオブジェクトは正しく比較されません。

文字列変換を絶えず行う必要はありません。これは、これらの複雑なオブジェクトをデータのツリーに変換するときに非常に可能性があります。ツリーの関係は、どのDBでも負担になります。 MongoDBでは難しいことではありません。

MongoDBでObjectIdの比較をどのように行いますか?

29
Elf Sternberg

ストレート==(または===)比較は、値ではなく参照によって2つのオブジェクトを比較します。したがって、両方がまったく同じインスタンスを参照している場合にのみ、trueと評価されます。

代わりに、equalsの-​​ ObjectID メソッドを使用して値を比較する必要があります。

story._id.equals(offref.ref)

@bendytreeがコメントで指摘しているように、いずれかの値がnullになる可能性がある場合(およびnullを等しいものとして比較する場合)、代わりに次を使用できます。

String(story._id) === String(offref.ref)
85
JohnnyHK

これは元の質問をいくらか超えていますが、ObjectIDの.equalsメソッドがfalseを返す場合があり、値がnullでなくても文字列比較がtrueを返す場合があります。例:

var compare1 = invitationOwningUser.toString() === linkedOwningUser.toString();
var compare2 = invitationOwningUser.equals(linkedOwningUser);
var compare3 = String(invitationOwningUser) === String(linkedOwningUser);
logger.debug("compare1: " + compare1 + "; " + "compare2: " + compare2 + "; " + "compare3: " + compare3);

出力:

compare1: true; compare2: false; compare3: true 

これは、invitationOwningUser(ObjectID)がMongooseスキーマを使用して作成されたコレクションから取得され、linkedOwningUser(これもObjectID)がMongooseを使用して作成されていないコレクション(通常のMongoDBメソッドのみ)から取得された場合に発生しました。

これは、invitationOwningUser(owningUserフィールド)を含むドキュメントです。

{
    "_id" : ObjectId("5782faec1f3b568d58d09518"),
    "owningUser" : ObjectId("5781a5685a06e69b158763ea"),
    "capabilities" : [
        "Read",
        "Update"
    ],
    "redeemed" : true,
    "expiry" : ISODate("2016-07-12T01:45:18.017Z"),
    "__v" : 0
}

これは、linkedOwningUser(owningUserフィールド)を含むドキュメントです。

{
    "_id" : ObjectId("05fb8257c95d538d58be7a89"),
    "linked" : [
        {
            "owningUser" : ObjectId("5781a5685a06e69b158763ea"),
            "capabilities" : [
                "Read",
                "Update"
            ]
        }
    ]
}

したがって、私にとっての結論として、.equalsメソッドではなく、文字列比較手法を使用してObjectIDを比較します。

1
Chris Prince