UniverseQuery 2.1.0
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package UniverseQuery --version 2.1.0
NuGet\Install-Package UniverseQuery -Version 2.1.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="UniverseQuery" Version="2.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="UniverseQuery" Version="2.1.0" />
<PackageReference Include="UniverseQuery" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add UniverseQuery --version 2.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: UniverseQuery, 2.1.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#addin nuget:?package=UniverseQuery&version=2.1.0
#tool nuget:?package=UniverseQuery&version=2.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Universe
A simpler way of querying a CosmosDb Namespace
Installation
dotnet add package Universe
How-to:
- Your models / cosmos entities should inherit from the interface
public class MyCosmosEntity : ICosmicEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
// The properties below are implementations from ICosmicEntity
public string id { get; set; }
public DateTime AddedOn { get; set; }
public DateTime ModifiedOn { get; set; }
[JsonIgnore]
public string PartitionKey => FirstName;
}
- Create a repository like so:
public class MyRepository : Galaxy<MyModel>
{
public MyRepository(CosmosClient client, string database, string container, string partitionKey) : base(client, database, container, partitionKey)
{
}
}
// If you want to see debug information such as the full Query text executed, use the format below:
public class MyRepository : Galaxy<MyModel>
{
public MyRepository(CosmosClient client, string database, string container, string partitionKey) : base(client, database, container, partitionKey, true)
{
}
}
- In your Startup.cs / Main method / Program.cs, configure the CosmosClient like so:
_ = services.AddScoped(_ => new CosmosClient(
System.Environment.GetEnvironmentVariable("CosmosDbUri"),
System.Environment.GetEnvironmentVariable("CosmosDbPrimaryKey"),
clientOptions: new CosmosClientOptions()
{
Serializer = new UniverseSerializer(), // This is from Universe.Options
AllowBulkExecution = true // This will tell the underlying code to allow async bulk operations
}
));
- In your Startup.cs / Main method / Program.cs, configure your CosmosDb repository like so:
_ = services.AddScoped<IGalaxy<MyModel>, MyRepository>(service => new MyRepository(
client: service.GetRequiredService<CosmosClient>(),
database: "database-name",
container: "container-name",
partitionKey: "/partitionKey"
));
- Inject your
IGalaxy<MyModel>
dependency into your classes and enjoy a simpler way to query CosmosDb
Basic Operations
Simple Query Operations
// Get a single document by id and partition key
(Gravity gravity, MyModel model) = await galaxy.Get("document-id", "partition-key-value");
// Basic query with a single filter condition
(Gravity gravity, MyModel model) = await galaxy.Get(
clusters: new List<Cluster>()
{
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.PropertyName), "value")
})
}
);
Creating Documents
// Create a single document
MyModel model = new MyModel
{
PropertyName = "value",
// Set other properties
};
(Gravity gravity, string id) = await galaxy.Create(model);
// Bulk create multiple documents
List<MyModel> models = new List<MyModel>
{
new MyModel { /* properties */ },
new MyModel { /* properties */ }
};
Gravity gravity = await galaxy.Create(models);
Updating Documents
// Update a single document
model.PropertyName = "new value";
(Gravity gravity, MyModel updatedModel) = await galaxy.Modify(model);
// Bulk update multiple documents
foreach (MyModel item in models)
{
item.PropertyName = "new value";
}
Gravity gravity = await galaxy.Modify(models);
Deleting Documents
// Delete a document
Gravity gravity = await galaxy.Remove("document-id", "partition-key-value");
Advanced Query Examples
Complex Queries with Multiple Conditions
// Query with multiple conditions in a single cluster
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>()
{
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.PropertyName), "value"),
new Catalyst(nameof(MyModel.NumberProperty), 123, Where: Q.Where.And)
})
}
);
// Query with multiple clusters (combining conditions with AND/OR)
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>()
{
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.PropertyName), "value"),
new Catalyst(nameof(MyModel.AnotherProperty), 123, Where: Q.Where.Or)
}, Where: Q.Where.And),
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.Status), "Active")
})
}
);
Special Operators
// Using In operator for array properties
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>()
{
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.Tags), "tag1", Operator: Q.Operator.In)
})
}
);
// Check if a property is defined
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>()
{
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.OptionalProperty), Operator: Q.Operator.Defined)
})
}
);
// Comparison operators
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>()
{
new Cluster(Catalysts: new List<Catalyst>
{
new Catalyst(nameof(MyModel.NumberProperty), 100, Operator: Q.Operator.Gt)
})
}
);
Sorting and Column Selection
// Query with sorting
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>() { /* query conditions */ },
sorting: new List<Sorting.Option>
{
new Sorting.Option(nameof(MyModel.PropertyName), Sorting.Direction.DESC)
}
);
// Query with column selection
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>() { /* query conditions */ },
columnOptions: new ColumnOptions(
Names: new List<string>
{
nameof(MyModel.id),
nameof(MyModel.PropertyName),
nameof(MyModel.AnotherProperty)
}
)
);
// Using TOP to limit results
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>() { /* query conditions */ },
columnOptions: new ColumnOptions(
Names: new List<string>
{
nameof(MyModel.id),
nameof(MyModel.PropertyName)
},
Top: 10
)
);
// Using DISTINCT
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>() { /* query conditions */ },
columnOptions: new ColumnOptions(
Names: new List<string>
{
nameof(MyModel.PropertyName)
},
IsDistinct: true
)
);
Pagination
// First page
(Gravity gravity, IList<MyModel> items) = await galaxy.Paged(
page: new Q.Page(25), // 25 items per page
clusters: new List<Cluster>() { /* query conditions */ }
);
// Access continuation token from the gravity object
string continuationToken = gravity.ContinuationToken;
// Next page using continuation token
(Gravity nextGravity, IList<MyModel> nextItems) = await galaxy.Paged(
page: new Q.Page(25, continuationToken),
clusters: new List<Cluster>() { /* same query conditions */ }
);
Group By Queries
// Group by a property
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>() { /* query conditions */ },
group: new List<string> { nameof(MyModel.Category) }
);
// Group by with COUNT
(Gravity gravity, IList<MyModel> results) = await galaxy.List(
clusters: new List<Cluster>() { /* query conditions */ },
columnOptions: new ColumnOptions(
Names: new List<string> { nameof(MyModel.Category) },
Count: true
)
);
Understanding the Gravity Object
The Gravity
object is returned by all operations and contains valuable information:
(Gravity gravity, MyModel model) = await galaxy.Get("document-id", "partition-key-value");
// Request Units consumed by the operation
double requestUnits = gravity.RU;
// Continuation token for pagination (only populated in Paged queries)
string continuationToken = gravity.ContinuationToken;
// Query information (only available when debug mode is enabled)
if (gravity.Query.HasValue)
{
string queryText = gravity.Query.Value.Text;
IEnumerable<(string, object)> parameters = gravity.Query.Value.Parameters;
Console.WriteLine($"Query: {queryText}");
foreach ((string name, object value) in parameters)
{
Console.WriteLine($"Parameter: {name} = {value}");
}
}
Error Handling
try
{
(Gravity gravity, MyModel model) = await galaxy.Get("non-existent-id", "partition-key");
}
catch (UniverseException ex)
{
// Universe-specific exceptions
Console.WriteLine($"Universe error: {ex.Message}");
}
catch (CosmosException ex)
{
// Cosmos DB specific exceptions
Console.WriteLine($"Cosmos error: {ex.Message}, Status: {ex.StatusCode}");
}
catch (Exception ex)
{
// Other errors
Console.WriteLine($"Error: {ex.Message}");
}
Performance Considerations
- Bulk Operations: Enable
AllowBulkExecution
in the CosmosClientOptions for efficient batch processing. - RU Tracking: The
Gravity
object provides RU consumption information for cost optimization. - Column Selection: Select only the columns you need to reduce data transfer.
- Debug Mode: The debug mode (enabled by passing
true
to the Galaxy constructor) provides query details but adds overhead. - Partition Key: Always consider your partition strategy for best performance.
Additional Information
For more detailed information about Universe, please check the API Documentation or the GitHub repository.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.Azure.Cosmos (>= 3.48.0)
- Newtonsoft.Json (>= 13.0.3)
- System.Text.Json (>= 9.0.3)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
View release on https://github.com/kuromukira/universe/releases