【问题标题】:Select subset of columns with yesod's persistent选择具有 yesod 持久性的列子集
【发布时间】:2014-08-16 14:14:46
【问题描述】:

我在 MongoDB 中使用持久性。 selectList 查询返回完整的产品列表并将它们加载到内存中;我只想返回列的一个子集。

Q1) 有没有办法只选择列的子集以便加载更多数据。为了更有效的查询?等效于 mongoDB 投影或 SQL SELECT <col,col...> 可能类似于 selectListCols 函数,它也将属性列表作为参数,并返回列表类型的列值而不是实体值。

Q2) 如果没有,我必须求助于手动 Database.MongoDB 查询,我可以从 Persistent 库中使用什么实用程序来修改由 selectList 生成的 mongodb 查询,以便我可以向其中添加 mongodb 投影并获取 BSON 值?

【问题讨论】:

    标签: mongodb haskell yesod persistent


    【解决方案1】:

    不,目前还没有办法做到这一点。持久性的 github 页面上有一个未解决的问题。总结是作者正在等到 ghc 7.10 来实现一些东西。链接到open issueclosed duplicate

    您可以使用原始驱动程序来实现您的查询。在库 mongoDB 中,请参阅 Database.MongoDB.Query.Projector。在已关闭的票证中,gregwebs 建议“persistent-mongoDB 现在有很多帮助者可以在原始驱动程序中使用一些持久类型安全(fieldName 肯定会成为你的预测朋友)”

    我不知道如何修改 selectList 生成的查询来执行投影。我怀疑当前的 API 是否有办法做到这一点,但我相信你可以通过修补持久性做到这一点。

    这是另一种解决方法:您是否考虑过定义不同的PersistEntitys 但保持集合名称相同?例如

    let mongoSettings = (mkPersistSettings (ConT ''MongoBackend)) { mpsGeneric = False }
      in  share [mkPersist mongoSettings, mkMigrate "migrateAll"][persistUpperCase|
    Thing sql=thing_collection
      name              String
      stuff    [Int32]
      deriving Show
    SmallThing sql=thing_collection
      name               String
      deriving Show
    
    |]
    

    请注意,sql=thing_collection 用于强制两个 PersistEntity 引用同一个 MongoDB 集合。

    此解决方法有一些折衷:

    优点:

    • 类型系统清楚地表明了查询将返回哪些字段。返回SmallThing 的查询显然不包含stuff。这使得进行查询并省略您稍后要阅读的字段成为编译时错误。

    缺点:

    • 您必须为每个变体定义一个PersistEntity。如果您的文档包含许多字段,并且您试图从查询中挤出最后一滴性能,那可能会有很多变体。
    • 您必须使变体保持同步。
    • 转换。你如何以一种类型安全、无样板的方式将Thing“向下转换”为SmallThing?例如。您手头有一个 Thing,并且您正在调用一个需要 SmallThing 的函数。

    你可以使用fromJSONtoJSON,但是aeson不支持ByteStrings,所以当你有ByteStrings时,JSON就没有用了。

    另外,请查看 toPersistFieldsfromPersistFields。也许它们可以用来代替 JSON。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多