Skip to content

Commit

Permalink
Merge branch 'release/20.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
dj-nitehawk committed Oct 1, 2020
2 parents 9a38f97 + acc3872 commit b57c610
Show file tree
Hide file tree
Showing 11 changed files with 338 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,4 @@ ASALocalRun/

# MFractors (Xamarin productivity tool) working folder
.mfractor/
Documentation/src
21 changes: 21 additions & 0 deletions Documentation/wiki/Queries-Count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Count entities
there are a couple of ways to get the count of entities stored in a collection.

### Count estimated total
```csharp
var count = await DB.CountEstimatedAsync<Author>();
```
you can get a fast estimate of total entities for a given entity type at the expense of accuracy.
the above will give you a rough estimate of the total entities using collection meta-data.

### Count total entities
```csharp
var count = await DB.CountAsync<Author>();
```
the above will give you an accurate count of total entities by running an aggregation query.

### Count matches for an expression
```csharp
var count = await DB.CountAsync<Author>(a => a.Title == "The Power Of Now");
```
you can get the number of entities that matches a given expression/filter with the above.
2 changes: 1 addition & 1 deletion Documentation/wiki/Queries-Linq.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# LINQ Queries
# LINQ queries

see the mongodb c# driver [linq documentation](http://mongodb.github.io/mongo-csharp-driver/2.11/reference/driver/crud/linq/) to see which LINQ operations are available.
also see the c# driver [expressions documentation](http://mongodb.github.io/mongo-csharp-driver/2.11/reference/driver/expressions/) to see all supported expressions.
Expand Down
1 change: 1 addition & 0 deletions Documentation/wiki/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
## [Find](Queries-Find.md)
## [LINQ](Queries-Linq.md)
## [Fluent Pipelines](Queries-Pipelines.md)
## [Count](Queries-Count.md)

# [Indexes](Indexes.md)
## [Fuzzy Text](Indexes-Fuzzy-Text-Search.md)
Expand Down
5 changes: 3 additions & 2 deletions MongoDB.Entities/MongoDB.Entities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
<Description>A data access library for MongoDB with an elegant api, LINQ support and built-in entity relationship management.</Description>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageProjectUrl>https://mongodb-entities.com</PackageProjectUrl>
<Version>20.2.0-beta2</Version>
<Version>20.2.0</Version>
<Copyright>Đĵ ΝιΓΞΗΛψΚ</Copyright>
<PackageReleaseNotes>- added ability to change default database at runtime
- improved db initialization
- improved file storage internals</PackageReleaseNotes>
- improved file storage internals
- new tests</PackageReleaseNotes>
<PackageId>MongoDB.Entities</PackageId>
<Product>MongoDB.Entities</Product>
<RepositoryUrl>https://github.com/dj-nitehawk/MongoDB.Entities</RepositoryUrl>
Expand Down
9 changes: 7 additions & 2 deletions docs/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -299,15 +299,20 @@
"title": "Multiple database support | MongoDB.Entities",
"keywords": "Multiple database support you can store and retrieve Entities in multiple databases on either a single server or multiple servers. the only requirement is to have unique names for each database. the following example demonstrates how to use multiple databases. Usage example: use the DB.DatabaseFor<T>() method to specify which database you want the Entities of a given type to be stored in. it is only neccessary to do that for the entities you want to store in a non-default database. the default database is the very first database your application initializes. all entities by default are stored in the default database unless specified otherwise using DatabaseFor . as such, the Book entities will be stored in the \"BookShop\" database and the Picture entities are stored in the \"BookShopFILES\" database considering the following code. await DB.InitAsync(\"BookShop\"); await DB.InitAsync(\"BookShopFILES\"); DB.DatabaseFor<Picture>(\"BookShopFILES\"); var book = new Book { Title = \"Power Of Now\" }; await book.SaveAsync(); //alternative: //// await DB.SaveAsync(book); var pic = new Picture { BookID = book.ID, Name = \"Power Of Now Cover Photo\" }; await pic.SaveAsync(); //alternative: //// await DB.SaveAsync(pic); await DB.Update<Picture>() .Match(p => p.ID == pic.ID) .Modify(p => p.Name, \"Updated Cover Photo\") .ExecuteAsync(); var result = await DB.Find<Picture>().OneAsync(pic.ID); Note an entity type is tied to a specific database by calling the DatabaseFor method with the database name on startup. that entity type will always be stored in and retrieved from that specific database only. it is not possible to save a single entity type in multiple databases. if you prefer to keep your database specifications inside the entity classes themselves, you could even call DatabaseFor in the static constructor like so: public class Picture : Entity { static Picture() => DB.DatabaseFor<Picture>(\"BookShopFILES\"); } Get database name from an entity instance or type var dbName = pic.DatabaseName(); var dbName = DB.DatabaseName<Book>(); the above methods will return the name of the database that the entity is stored in. if not specifically attached to seperate db, it will return the name of the default database. Limitations cross-database relationships with Many<T> is not supported. no cross-database joins/ look-ups as the driver doesn't support it. storing a single entity type in multiple datbases is not supported. Removal of DB instances in v20 if you've used an earlier verion than v20 of this library, you may have used DB instances for performing operations rather than using the static DB class as the entrypoint. In v20, the DB instance support was removed in order to simplify the codebase and optimize performance as that release was a major jump in version with breaking changes to the API. DB instances were a neccessity before v13 in order to support multiple database access. that requirement was removed in v13 after re-architecting the library internals and it was optional to use DB instances up until v20. it can be argued that DB instances are useful for dependency injection but, ideally you should be injecting your repositories (that wrap up the DB methods) into your controllers/ services, not the DB instances directly. if you don't need to unit test or plan to swap persistance technology at a future date, then there's no need to use dependency injection and you are free to do everything via the DB static methods. it is however, recommended that you encapsulate all data access logic in repository or manager classes in order to isolate data persistance logic from your application logic. Tip as an alternative, have a look at vertical slice architecture as done here for a far superior developer experience compared to the commonly used layerd+di+repositories mess."
},
"wiki/Queries-Count.html": {
"href": "wiki/Queries-Count.html",
"title": "Count entities | MongoDB.Entities",
"keywords": "Count entities there are a couple of ways to get the count of entities stored in a collection. Count estimated total var count = await DB.CountEstimatedAsync<Author>(); you can get a fast estimate of total entities for a given entity type at the expense of accuracy. the above will give you a rough estimate of the total entities using collection meta-data. Count total entities var count = await DB.CountAsync<Author>(); the above will give you an accurate count of total entities by running an aggregation query. Count matches for an expression var count = await DB.CountAsync<Author>(a => a.Title == \"The Power Of Now\"); you can get the number of entities that matches a given expression/filter with the above."
},
"wiki/Queries-Find.html": {
"href": "wiki/Queries-Find.html",
"title": "Find queries | MongoDB.Entities",
"keywords": "Find queries several overloads are available for finding entities as shown below. Find one by ID var author = await DB.Find<Author>().OneAsync(\"ID\"); Find many by lambda var authors = await DB.Find<Author>().ManyAsync(a => a.Publisher == \"Harper Collins\"); Find many by filter var authors = await DB.Find<Author>() .ManyAsync(f=> f.Eq(a=>a.Surname,\"Stark\") & f.Gt(a=>a.Age,35)); Tip all the filter definition builder methods of the official driver are available for use as shown above. Find by 2D coordinates var cafes = await DB.Find<Cafe>() .Match(c => c.Location, new Coordinates2D(48.857908, 2.295243), 1000) .ExecuteAsync() Tip see this tutorial for a detailed walkthrough. Find by aggregation expression ($expr) var authors = await DB.Find<Author>() .MatchExpression(\"{$gt:['$TotalSales','$SalesGoal']}\") .ExecuteAsync(); Tip aggregation expressions lets you refer to properties of the same entity using the $ notation as shown above. Advanced find Sorting, paging and projecting var authors = await DB.Find<Author>() .Match(a => a.Age > 30) .Sort(a => a.Age, Order.Descending) .Sort(a => a.Name, Order.Ascending) .Skip(1).Limit(1) .Project(a => new Author { Name = a.Name }) .ExecuteAsync(); the search criteria is specified using .Match() which takes either an ID , lambda expression , filter expression , geospatial , or full/fuzzy text search query . sorting is specified using .Sort() which takes in a lambda for the property to sort by and in which order. .Sort() can be used multiple times in order to specify multiple sorting stages. when doing text queries, you can sort the results by mongodb's 'meta text score' by using the .SortByTextScore() method. how many items to skip and take are specified using .Skip() and .Limit() Projections to avoid the complete entity being returned, you can use .Project() with a lambda expression to get back only the properties you need as shown above. it is also possible to use projection builder methods like so: .Project(p => p.Include(\"Name\").Exclude(\"Surname\")) Tip to be able to chain projection builder methods like above, please add the import statement using MongoDB.Driver; to your class. Projection with exclusions it is also possible to specify an exclusion projection with a new expression like so: var res = await DB.Find<Author>() .Match(a => a.ID == \"xxxxxxxxxxx\") .ProjectExcluding(a => new { a.Age, a.Name }) .ExecuteSingleAsync(); doing so will return an Author entity with all the properties populated except for the Age and Name properties. Project to a different type in order to project to a different result type than the input entity type, simply use the generic overload like so: var name = await DB.Find<Author,string>() .Match(a => a.ID == \"xxxxxxxxxxx\") .Project(a => a.FirstName + \" \" + a.LastName) .ExecuteSingleAsync(); Execute an .Execute*() method is called finally to get back the result of the find command. you can also get a cursor back instead of materialized results by calling .ExecuteCursorAsync() at the end. Tip there are 3 variations of Execute () * you can use. ExecuteAsync() which will return a list of matched entities. ExecuteSingleAsync() which will return only 1 matched entity and will throw an exception if more than 1 entity is matched. ExecuteFirstAsync() which will return the first matched entity. all variations will return a null/default value if nothing was matched."
},
"wiki/Queries-Linq.html": {
"href": "wiki/Queries-Linq.html",
"title": "LINQ Queries | MongoDB.Entities",
"keywords": "LINQ Queries see the mongodb c# driver linq documentation to see which LINQ operations are available. also see the c# driver expressions documentation to see all supported expressions. Tip don't forget to first import the mongodb linq extensions with using MongoDB.Driver.Linq; Query collections var author = await (from a in DB.Queryable<Author>() where a.Name.Contains(\"Eckhart\") select a).FirstOrDefaultAsync(); Collection shortcut var authors = from a in author.Queryable() select a; this .Queryable() is an IQueryable for the whole collection of Authors which you can write queries against. Forward relationship access every Many<T> property gives you access to an IQueryable of child entities. var authors = from a in book.Authors.ChildrenQueryable() select a; this .ChildrenQueryable() is an already filtered IQueryable of child entities. For ex: the above .ChildrenQueryable() is limited to only the Authors of that particular Book entity. It does not give you access to all of the Author entities in the Authors collection. Reverse relationship access for example, if you'd like to get all the books belonging to a genre, you can do it with the help of .ParentsQueryable() like so: var books = book.Genres .ParentsQueryable<Book>(\"GenreID\"); you can also pass in an IQueryable of genres and get back an IQueryable of books like shown below: var query = genre.Queryable() .Where(g => g.Name.Contains(\"Music\")); var books = book.Genres .ParentsQueryable<Book>(query); it is basically a convenience method instead of having to do a manual join like the one shown below in order to access parents of one-to-many or many-to-many relationships. Relationship joins Many<T>.JoinQueryable() gives you access to all the join records of that particular relationship. A join record has two properties ParentID and ChildID that you can use to gain access to parent Entities like so: var books = from j in book.Authors.JoinQueryable() join b in book.Queryable() on j.ParentID equals b.ID select b; Counting children you can get how many entities are there in the opposite side of any relationship as shown below: var authorCount = await book.Authors.ChildrenCountAsync(); var bookCount = await author.Books.ChildrenCountAsync();"
"title": "LINQ queries | MongoDB.Entities",
"keywords": "LINQ queries see the mongodb c# driver linq documentation to see which LINQ operations are available. also see the c# driver expressions documentation to see all supported expressions. Tip don't forget to first import the mongodb linq extensions with using MongoDB.Driver.Linq; Query collections var author = await (from a in DB.Queryable<Author>() where a.Name.Contains(\"Eckhart\") select a).FirstOrDefaultAsync(); Collection shortcut var authors = from a in author.Queryable() select a; this .Queryable() is an IQueryable for the whole collection of Authors which you can write queries against. Forward relationship access every Many<T> property gives you access to an IQueryable of child entities. var authors = from a in book.Authors.ChildrenQueryable() select a; this .ChildrenQueryable() is an already filtered IQueryable of child entities. For ex: the above .ChildrenQueryable() is limited to only the Authors of that particular Book entity. It does not give you access to all of the Author entities in the Authors collection. Reverse relationship access for example, if you'd like to get all the books belonging to a genre, you can do it with the help of .ParentsQueryable() like so: var books = book.Genres .ParentsQueryable<Book>(\"GenreID\"); you can also pass in an IQueryable of genres and get back an IQueryable of books like shown below: var query = genre.Queryable() .Where(g => g.Name.Contains(\"Music\")); var books = book.Genres .ParentsQueryable<Book>(query); it is basically a convenience method instead of having to do a manual join like the one shown below in order to access parents of one-to-many or many-to-many relationships. Relationship joins Many<T>.JoinQueryable() gives you access to all the join records of that particular relationship. A join record has two properties ParentID and ChildID that you can use to gain access to parent Entities like so: var books = from j in book.Authors.JoinQueryable() join b in book.Queryable() on j.ParentID equals b.ID select b; Counting children you can get how many entities are there in the opposite side of any relationship as shown below: var authorCount = await book.Authors.ChildrenCountAsync(); var bookCount = await author.Books.ChildrenCountAsync();"
},
"wiki/Queries-Pipelines.html": {
"href": "wiki/Queries-Pipelines.html",
Expand Down
20 changes: 16 additions & 4 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,18 @@
"is_incremental": false,
"version": ""
},
{
"type": "Conceptual",
"source_relative_path": "wiki/Queries-Count.md",
"output": {
".html": {
"relative_path": "wiki/Queries-Count.html",
"hash": "g3Zj5W4bw2tt0c5Aqm4F6w=="
}
},
"is_incremental": false,
"version": ""
},
{
"type": "Conceptual",
"source_relative_path": "wiki/Queries-Find.md",
Expand All @@ -840,7 +852,7 @@
"output": {
".html": {
"relative_path": "wiki/Queries-Linq.html",
"hash": "Sbw8TKzdHFpe0KD3iACEsw=="
"hash": "80R9NsxmgcgTIc2kbs4CIw=="
}
},
"is_incremental": false,
Expand Down Expand Up @@ -924,7 +936,7 @@
"output": {
".html": {
"relative_path": "wiki/toc.html",
"hash": "6CMdp7sC1Nb5ZpwYyDL03w=="
"hash": "rZCJPNK8yVdHKszNy+d1Og=="
}
},
"is_incremental": false,
Expand All @@ -943,14 +955,14 @@
"ConceptualDocumentProcessor": {
"can_incremental": true,
"incrementalPhase": "build",
"total_file_count": 25,
"total_file_count": 26,
"skipped_file_count": 25
},
"ManagedReferenceDocumentProcessor": {
"can_incremental": true,
"incrementalPhase": "build",
"total_file_count": 43,
"skipped_file_count": 13
"skipped_file_count": 43
},
"ResourceDocumentProcessor": {
"can_incremental": false,
Expand Down
Loading

0 comments on commit b57c610

Please sign in to comment.