Zaid-Ajaj / LiteDB.FSharp

Advanced F# Support for LiteDB, an embedded NoSql database for .NET with type-safe query expression through F# quotations
MIT License
180 stars 22 forks source link

The client code that uses the library must know a lot about it. #28

Closed srlopez closed 5 years ago

srlopez commented 5 years ago

Hi again, Sorry for the list of issues I'm publishing, but I do it for the benefit of the code and to be clearer readability.

I think that the code that uses the library must know a lot about it.

First: The code must know about the name of the values. When I want to delete a record by its identifier, expressing it clearly. The code computers.Delete(Query.LT("Id", BsonValue(myPc.Id-3))) does not work. In the register, Id is a value, but as a programmer I have to know that it is stored as _id, in order to use it, and so computers.Delete(Query.LT("_id", BsonValue(myPc.Id-3))) works correctly. I don't know if it's so by design, or it's a simple mistake that can be easily fixed.

Second: The code must know the underlying Bson format. For each Query/Find I must indicate previously a conversion to Bson, as in the previous example, or the simple computers.FindById(BsonValue(1)) or computers.Find(Query.EQ("Manufacturer", BsonValue("System77"))) |> Seq.iter (printfn "%A"). It's harder to read. In the C# version it seems to me that the conversion is done internally.

var results = col.Find(Query.StartsWith("Name", "Jo"));
var results = col.Find(Query.GT("Products[*].Price", 100))

I think doing it inside the wrapper would help to clarify the code and it would be more F# idiomatic. It's a simple modification, but it's structural. Maybe for the next version 3.

Tell me what you think. And thank you again

Zaid-Ajaj commented 5 years ago

Hello @srlopez, you seem to have found the problem that this library solves for F# ;) The description says: "... with type-safe query expression through F# quotations" which is how you should query your data without needing to know about BsonDocuments.

In the README there are many examples of querying the data using quotations but you have to open the namespace LiteDB.FSharp.Extensions and your LiteCollection will have extensions methods:

let collection = db.GetCollection<MyType>("collection")
collection.findOne (fun item -> ... )
collection.findMany (fun item -> ... )
collection.tryFindOne (fun item -> ... )
collection.delete (fun item -> ....)
collection.fullseach <@ fun item -> item.Prop @> (fun prop -> ...)
collection.where <@ fun item -> item.Prop @> (fun prop -> ...)

Example

open LiteDB
open LiteDB.FSharp
open LiteDB.FSharp.Extensions

type Person = { Id: int; Name: string; Age: int; Email: string } 
let people = db.GetCollection<Person>("people ")

// find by Id
let exactPerson = people.findOne (fun p -> p.Id = 1)

let john = people.findOne (fun person -> person.Name.StartsWith "John")

let adults = people.findMany (fun person -> person.Age >= 18) 

let nonEmptyEmails = people.findMany (fun person -> not (string.IsNullOrEmpty person.Email) )

// composite queries
let adultDoe = people.findMany (fun person -> person.Age >= 18 && person.Name.Contains "Doe")

I thought I properly documented these function but I guess I can never have enough documentation :smile:

Zaid-Ajaj commented 5 years ago

Is the problem resolved? I will close this issue for now, please re-open or open an other issue if encounter other problems