Select a subset of Yesod-enabled columns

I am using Persistent with MongoDB. The query selectList

returns the complete list of products and loads them into memory; I would like to return only a subset of the columns.

Q1) Is there a way to select only a subset of the columns so that more data can be loaded. For a more efficient query? Equivalent to mongoDB or SQL projection Possibly SELECT <col,col...>

something like the selectListCols function that also takes a list of attributes as an argument and returns typed column values ​​instead of entity values.

Q2) If not, and I have to resort to Database.MongoDB manual query, what utility can I use from the persistent library to modify the mongodb query generated by selectList so that I can add a mongodb projection to it and get the BSON value

+3


source to share


1 answer


No, there is no way to do it yet. There is an open question about the permanent github page. The summary is that the authors are waiting until ghc 7.10 does nothing. Link to open issue and closed duplicate .

You can use a raw driver to implement your requests. For the mongoDB library see Database.MongoDB.Query.Projector. In a closed ticket, gregwebs suggests "There are many helpers in persistent-mongoDB now for leveraging some persistent type safety with a raw driver (the field name will definitely be your friend for predictions)"

I don't know how to change the query generated by the selectList to do the projection. I doubt there is a way to do this with the current API, but I'm sure you can do it with the fixed constant.

Here's another workaround: do you think you are specifying different PersistEntity

but keeping the collection name the same? For example.

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

|]

      

Note what is sql=thing_collection

used to force the PersistEntity to reference the same MongoDB collection.

There are some tradeoffs in this workaround:



Pros:

  • It was clear in the type system which fields would be returned from the query. The query returning SmallThing

    obviously does not contain stuff

    . It makes a compile-time error to make the request and omit the field you want to read later.

Minuses:

  • You will need to define PersistEntity

    for each option. This can be many options if you have documents with many fields and are trying to squeeze every last performance out of your queries.
  • You must sync the options.
  • Conversion. How do you "downgrade" Thing

    to SmallThing

    type safe, no templates? For example. you have Thing

    and you are calling the function expecting SmallThing

    .

You can use fromJSON

and toJSON

, but aeson doesn't support ByteString

s, so JSON won't be useful if you have ByteString

s.

Also check toPersistFields

and fromPersistFields

. Perhaps they can be used instead of JSON.

+1


source







All Articles