将Mongodb ObjectId自动映射到字符串和从字符串映射



我正在使用Monger库从Clojure访问Mongo数据库。有一件事让我很恼火,那就是在ObjectId实例和字符串之间来回切换。

例如,这段代码(mc/find-maps "posts" {})将计算为映射,_id条目的值设置为ObjectId类的实例,而在我的应用程序中,我发现简单地将其作为一个字符串更有用,因为我知道它是唯一的。

另一方面,对于像(mc/find-map-by-id "posts" (new ObjectId id))这样的表达式,其中我确实为id参数使用了一个String对象,我必须使用它来构造ObjectId的实例。

有没有一种方法可以使_id的值在应用程序中的Strings和mongo端的ObjectId之间自动透明地转换?某种选项在启用时会创建带有id字符串表示的映射,反之亦然,在查询中用作参数时会转换id字符串表示t对象id?

如果没有,还有哪些其他策略可用?

我和你分享这一点上的痛苦。返回ObjectID是很烦人的,因为您总是必须来回转换,如果您忘记了,那么很难发现错误。

您最好的选择可能是包装驱动程序代码以自动进行转换。因此,将find、findOne、insert替换为一个查看类型并自动进行转换的瘦包装器,无论您是进入还是退出。

不幸的是,我认为没有更简单的方法了。

我参加聚会有点晚了,但为了子孙后代,我不得不提一提。

我不想解决自动str->ObjectID部分,因为让代码了解哪些字符串必须被视为ObjectID,哪些不能被视为。但对于ObjectID->str的一半,有一个解决方案。

我最终扩展了monger.conversion/ConvertFromDBObject协议,如下所示:

(extend-protocol ConvertFromDBObject
    ObjectId
    (from-db-object [input keywordize]
      (str input)))

from-db-object在所有读作映射操作中被调用,因此这解决了读取部分。至于将ObjectID转换为插入和更新结果的字符串,我还没有找到任何优雅的解决方案,也没有为映射扩展相同的协议,并在包装器函数中对插入和更新操作的结果调用from-db-object。为地图扩展协议看起来是这样的(完全是从DBObject:的原始实现中窃取的

(extend-protocol ConvertFromDBObject
    ; copied over from the implementation for DBObject
    clojure.lang.IPersistentMap
    (from-db-object [input keywordize]
      (reduce (if keywordize
                (fn [m ^String k]
                  (assoc m (keyword k) (from-db-object (.get input k) true)))
                (fn [m ^String k]
                  (assoc m k (from-db-object (.get input k) false))))
              {} (.keySet input))))

相关内容

  • 没有找到相关文章

最新更新