2012-06-16 23 views
26

我有一个直接的工具来构建文档集合,然后自动格式化它们以用于在ExpressJS上编写的EPUB或LaTeX呈现。我使用Coffeescript,如果重要的话(我怀疑它)。Mongoose:ObjectId比较失败并不一致

使用猫鼬,我有以下几点:

DocumentSchema = new Schema 
    title:  String 

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

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

Offrefs没有指定什么它指的是因为,因为我希望能够遏制一些粘合剂其他粘合剂,创建逻辑集合:“这些是为打印机“,”这些是为EPUB,“”这些只是网络,“等(我已经剥离了所有杂项的东西了。)

不幸的是,我已经跑进查询,其中,检索物体

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

而且两个确实看起来一样。但是:

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

而且两个引用的最后两个视觉对比,他们相同的ID号,但ObjectId对象不正确地比较。

我不想要做的字符串转换不断,这是当我将这些复杂的对象为数据树木强烈方法可行。树木关系是任何数据库中的熊;他们在MongoDB中不应该很难。

你如何在MongoDB中进行ObjectId比较?

回答

76

的直==(或===)比较将通过引用,而不是值的两个对象进行比较。所以如果它们都引用同一个实例,那么它只会评估为真。

相反,你应该使用的ObjectIDequals方法来比较它们的值:

story._id.equals(offref.ref) 

正如评论@bendytree笔记,如果任一值可以是空(和你想的空值比较平等),那么你可以改用以下内容:

String(story._id) === String(offref.ref) 
+8

耶,无证的功能。 – peterjwest

+0

所以这和mongoose.Schema.Types.ObjectID不一样? 他们的文档暗示它只有'auto'方法: http://mongoosejs.com/docs/api.html#schema-objectid-js – peterjwest

+1

@peterjwest右键,'mongoose.Schema.Types.ObjectId'真的只是用作模式定义中的字段型元数据。 – JohnnyHK

1

这又有点超越了原来问的问题,但我发现,对象ID年代.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(一个对象ID)从集合来使用猫鼬架构创建和linkedOwningUser(也是一个对象ID)使用未创建的集合来发生这种情况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" 
      ] 
     } 
    ] 
} 

所以,作为对我来说是底线,我将使用字符串比较技术来比较ObjectID,而不是.equals方法。

+0

这似乎是一个关键问题。你知道为什么猫鼬看起来不一样吗?我在'MongooseBuffer.mixin.equals'中猜测它是'if(!Buffer.isBuffer(other))'这看起来是一种优化来保存扫描内容。我现在很担心!我只是将我的.toString转换为.equals。 (但我只使用猫鼬==猫鼬,所以我想这不是一个风险)。 – scipilot