32

私は、ドキュメントのコレクションを構築し、それらを EPUB または LaTeX レンダリング用に自動的にフォーマットするための簡単なツールを持っています。これは、ExpressJS の上に記述されています。それが問題なら、私はCoffeescriptを使用しています(私はそれを疑っています)。

Mongoose を使用すると、次のようになります。

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 つの参照を視覚的に比較すると、 ID 番号同じですが、ObjectIdオブジェクトが正しく比較されていません。

これらの複雑なオブジェクトをデータのツリーに変換している場合、文字列変換を頻繁に行う必要はありません。ツリー関係は、どの DB においても重要です。MongoDB では難しくありません。

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

4

2 に答える 2

96

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

代わりに、のequals方法を使用ObjectIDしてそれらの値を比較する必要があります。

story._id.equals(offref.ref)

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

String(story._id) === String(offref.ref)
于 2012-06-16T03:32:19.023 に答える
1

これは元の質問とは多少異なりますが、値が null でない場合でも文字列比較で true が返される場合に、ObjectID の .equals メソッドが false を返すことがわかりました。例:

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 を比較します。

于 2016-07-11T01:58:37.457 に答える