{"id":16282926,"url":"https://github.com/angelmunoz/mondocks","last_synced_at":"2026-01-14T04:23:38.283Z","repository":{"id":43893139,"uuid":"315120607","full_name":"AngelMunoz/Mondocks","owner":"AngelMunoz","description":"An alternative way to interact with MongoDB databases from F# that allows you to use mongo-idiomatic constructs","archived":true,"fork":false,"pushed_at":"2023-09-26T03:15:37.000Z","size":417,"stargazers_count":44,"open_issues_count":4,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-19T12:19:22.259Z","etag":null,"topics":["computation-expressions","dotnet","dotnet-core","dotnet5","fsharp","library","mongo","mongodb","nosql"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AngelMunoz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"daniel_tuna","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-11-22T19:57:11.000Z","updated_at":"2024-10-21T03:49:57.000Z","dependencies_parsed_at":"2024-01-09T20:19:42.697Z","dependency_job_id":null,"html_url":"https://github.com/AngelMunoz/Mondocks","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FMondocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FMondocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FMondocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngelMunoz%2FMondocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AngelMunoz","download_url":"https://codeload.github.com/AngelMunoz/Mondocks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244538533,"owners_count":20468730,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computation-expressions","dotnet","dotnet-core","dotnet5","fsharp","library","mongo","mongodb","nosql"],"created_at":"2024-10-10T19:12:02.868Z","updated_at":"2026-01-14T04:23:38.247Z","avatar_url":"https://github.com/AngelMunoz.png","language":"F#","funding_links":["https://ko-fi.com/daniel_tuna"],"categories":[],"sub_categories":[],"readme":"[mongodb extended json]: https://docs.mongodb.com/manual/reference/mongodb-extended-json/\n\n# Mondocks\n\n![nuget](https://badgen.net/nuget/v/mondocks)\n[![Binder](https://notebooks.gesis.org/binder/badge_logo.svg)](https://notebooks.gesis.org/binder/v2/gh/AngelMunoz/Mondocks/HEAD)\n\n\u003e ```\n\u003e dotnet add package Mondocks.Net\n\u003e # or for fable/nodejs\n\u003e dotnet add package Mondocks.Fable\n\u003e ```\n\n\u003e This library is based on the mongodb extended json spec and mongodb manual reference\n\u003e\n\u003e https://docs.mongodb.com/manual/reference/mongodb-extended-json/ \u003e https://docs.mongodb.com/manual/reference/command/\n\nThis library provides a set of familiar tools if you work with mongo databases and can be a step into more F# goodies, it doesn't prevent you from using the usual MongoDB/.NET driver so you can use them side by side. It also can help you if you have a lot of flexible data inside your database as oposed to the usual strict schemas that F#/C# are used to from SQL tools, this provides a DSL that allow you to create `MongoDB Commands (raw queries)` leveraging the dynamism of anonymous records since they behave almost like javascript objects.\nWriting commands should be almost painless these commands produce a JSON string that can be utilized directly on your application or even copy/pasted into the mongo shell.\nCommands are kind of a version of `raw sql queries` but they allow you to do what you already know how to do without much changes to the objects you might be manipulating already.\nIdeally this library is meant to be used mostly with records and anonymous records to imitate `mongodb` queries\n\n## Sample Usage\n\nCheck out this quick sample of what you can do right now\n\n\u003e You can also check this [gist](https://gist.github.com/AngelMunoz/35cf2bc439da9969664f9987f7109ee3)\n\n```fsharp\nopen System\nopen MongoDB.Driver\nopen MongoDB.Bson\nopen Mondocks.Queries\nopen Mondocks.Types\n\ntype User = { _id: ObjectId; name: string; age: int }\nlet createUsers minAge maxAge =\n    let random  = Random()\n    insert \"users\" {\n        documents\n            [   // an anonymous object that does not include a null _id\n                {| name = \"Peter\"; age = random.Next(minAge, maxAge); |}\n                {| name = \"Sandra\"; age = random.Next(minAge, maxAge); |}\n                {| name = \"Mike\"; age = random.Next(minAge, maxAge); |}\n                {| name = \"Perla\"; age = random.Next(minAge, maxAge); |}\n                {| name = \"Updateme\"; age = 1; |}\n                {| name = \"Deleteme\"; age = 50; |}\n            ]\n    }\nlet getUsersOverAge (age: int) =\n    find \"users\" {\n        // equivalent to a mongo query filter\n        // { age: { $gt: age } }\n        filter {| age = {| ``$gt``= age |} |}\n        limit 2\n        skip 1\n    }\nlet updateUser (name: string) (newName: string) =\n    update \"users\" {\n        updates\n            [ { // you can do mongo queries like\n                // {| ``$or`` = [] |} -\u003e { $or: [] }\n                q = {| name = name |}\n                u = {| name = newName; age = 5 |}\n                multi = Some false\n                upsert = Some false\n                collation = None\n                arrayFilters = None\n                hint = None }\n            ]\n    }\nlet deleteUser (name: string) =\n    delete \"users\" {\n        deletes\n           [ { q = {| name = name |}\n               limit = 1\n               collation = None\n               hint = None\n               comment = None }\n        ]\n    }\n[\u003cEntryPoint\u003e]\nlet main argv =\n    let client = MongoClient(\"mongodb://localhost:27017\")\n    let db = client.GetDatabase(\"mondocks\")\n\n    let userscmd = createUsers 15 50\n    let result = db.RunCommand\u003cInsertResult\u003e(JsonCommand userscmd)\n    printfn $\"InsertResult: %A{result}\"\n\n    let over20 = getUsersOverAge 20\n    let result = db.RunCommand\u003cFindResult\u003cUser\u003e\u003e(JsonCommand over20)\n    printfn $\"FindResult Ok: %f{result.ok}\"\n    result.cursor.firstBatch |\u003e Seq.iter (fun value -\u003e printfn $\"%A{value}\")\n\n    let updatecmd = updateUser \"Updateme\" \"Updated\"\n    let result = db.RunCommand\u003cUpdateResult\u003e(JsonCommand updatecmd)\n    printfn $\"UpdateResult: %A{result}\"\n\n    let deletecmd = deleteUser \"Deleteme\"\n    let result = db.RunCommand\u003cDeleteResult\u003e(JsonCommand deletecmd)\n    printfn $\"DeleteResult: %A{result}\"\n\n    0\n```\n\nIf you want to see what else is available check the `samples` directory\n\n# Documentation\n\nRight now the documentation is provided via .NET Interactive notebooks.\nThere are three ways ways to ineract with it\n\n- The [Notebooks](https://github.com/AngelMunoz/Mondocks/tree/main/notebooks) directory contains jupyter notebooks that you can download and open them with the [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.dotnet-interactive-vscode) to interact with them in real time.\n- If you don't want to download anything you can still check the notebooks online, click on [![Binder](https://notebooks.gesis.org/binder/badge_logo.svg)](https://notebooks.gesis.org/binder/v2/gh/AngelMunoz/Mondocks/HEAD) to go to the binder website and check the notebooks online\n\n- If your editor supports doc comments, you should be able to see samples as well, part of the source code is documented that way, you should even see examples in the editor tooltips in some cases\n\n# Serialization\n\nThis might be very important for you, in case the default serialization strategy doesn't work for you, you should be able to fall back to the core `Mondocks` library where the general abstractions are defined.\n\nFor example in Fable we just use `JSON.stringify(value)`\n\n```fsharp\nmodule Json =\n    let Serialize value = toPlainJsObj value |\u003e JSON.stringify\n\nmodule Aggregation =\n\n    let count = CountCommandBuilder(Json.Serialize)\n```\n\nand in .NET we use System.Text.Json\n\n```fsharp\nmodule Json =\n    // ... a bunch of converters ...\n    type Serializer() =\n        static member Serialize\u003c'T\u003e(value: 'T, [\u003cOptional\u003e] ?options: JsonSerializerOptions) =\n            JsonSerializer.Serialize\u003c'T\u003e(value, defaultArg options defaults)\n\nmodule Aggregation =\n    let count = CountCommandBuilder(Json.Serializer.Serialize)\n```\n\nIf our current serialization strategy doesn't work for you (or want to support something like Thoth.Json), you may supply a serialization function for your builder\n\n```fsharp\n\nmodule MyAggregation =\n\n    let serialize (value: obj) =\n        // ... do the serialization thing ...\n\n    let myCount = CountCommandBuilder(fun value -\u003e serialize value)\n```\n\n# Goals\n\n- Emit 100% compatible json with https://docs.mongodb.com/manual/reference/command/ and https://docs.mongodb.com/manual/reference/mongodb-extended-json\n- Provide Tools that are familiar from those who come from other environments to be productive since day 1\n- Provide Types to ease the transition between command execution and it's return types\n- Provide CE's to generate sub types of the main command definitions (e.g. index)\n\n## Non Required Extras\n\n- provide helpers to write different syntax (e.g. `filter (fun m -\u003e m.prop = value)`, `filter (\"prop\" gt 10)`)\n\n## Non Goals\n\n- Convert this into a document mapper\n- Provide 100% of the mongo commands\n- Provide a 100% F# idiomatic solution\n\nThis is a work in progress, you can help providing feedback about it's usage\n\n\u003e Thanks for the early feedback in twitter from Isaac, Zaid, Alexey, Alexander, and the F# community\n\u003e you can follow it on the first [issue](https://github.com/AngelMunoz/Mondocks/issues/1)\n\n```\n\n```\n\n```\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangelmunoz%2Fmondocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangelmunoz%2Fmondocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangelmunoz%2Fmondocks/lists"}