自动将MongoDB ObjectId转换为字符串并从字符串转换回ObjectId的映射

7
我正在使用Monger库从Clojure访问Mongo数据库,其中一件令人讨厌的事情是在ObjectId实例和字符串之间来回切换。
例如,这段代码 (mc/find-maps "posts" {}) 将计算为具有 _id 键设置为 ObjectId 类的实例的映射,而在我的应用程序中,我发现将其作为字符串更有用,因为我知道它是唯一的。
另一方面,对于表达式如: (mc/find-map-by-id "posts" (new ObjectId id)) 其中我使用 String 对象作为 id 参数,我必须使用它来构造一个 ObjectId 实例。
是否有一种方法可以使 _id 值自动透明地在应用程序和Mongo之间转换为字符串和 ObjectId?是否有某种选项可在启用时创建具有 ID 字符串表示的映射,并且在查询参数中使用字符串表示形式的 ID 时将其转换为对象 ID?
如果没有,还有哪些其他策略可用?
2个回答

1

我理解你的痛点。获取ObjectID很麻烦,因为你总是需要来回转换,如果忘记了,那就很难发现这个bug。

你最好的选择可能是包装驱动程序代码以自动进行转换。所以用一个薄包装器替换find、findOne、insert,它会查看类型并自动进行转换,无论你是进入还是离开。

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


0

我有点晚来参加这个派对,但必须为未来的一代提到。

我并不想解决自动 str->ObjectID 部分,因为要让代码理解哪个字符串必须被视为 ObjectID,哪个不必如此,这样会变得非常复杂。但是对于 ObjectID->str 的部分,有一个解决方案。

最终,我通过扩展 monger.conversion/ConvertFromDBObject 协议来实现:

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

from-db-object 在所有读取为映射操作中被调用,因此这解决了读取部分的问题。至于将ObjectIDs转换为字符串以便于插入和更新结果,我没有找到任何优雅的解决方案,并在我的包装函数中扩展了相同的协议,对插入和更新操作的结果调用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))))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接