Elasticsearch
Gridify.Elasticsearch is an extension of Gridify, that provides an ability to generate Elasticsearch DSL queries.
Gridify.Elasticsearch Package
The Gridify.Elasticsearch
package has a bunch of extension methods that allow to convert Gridify filters and sortings to Elasticsearch DSL queries using Elastic.Clients.Elasticsearch .NET client.
Installation
Package Manager
Install-Package Gridify.Elasticsearch -Version 2.15.1
.NET CLI
dotnet add package Gridify.Elasticsearch --version 2.15.1
Configurations
CustomElasticsearchNamingAction
Specifies how field names are inferred from CLR property names. By default, Elastic.Clients.Elasticsearch uses camel-case property names.
- If
null
(default behavior) CLR propertyEmailAddress
will be inferred asemailAddress
Elasticsearch document field name. - If, e.g.,
p => p
, the CLR propertyEmailAddress
will be inferred asEmailAddress
Elasticsearch document field name.
Default
await client.SearchAsync<User>(s => s
.Index("users")
.ApplyFiltering("emailAddress = test@test.com"));
this will make the next Elasticsearch query:
GET users/_search
{
"query": {
"term": {
"emailAddress.keyword": {
"value": "test@test.com"
}
}
}
}
Customized:
GridifyGlobalConfiguration.CustomElasticsearchNamingAction = p => $"_{p}_";
await client.SearchAsync<User>(s => s
.Index("users")
.ApplyFiltering("emailAddress = test@test.com"));
this will make the next Elasticsearch query:
GET users/_search
{
"query": {
"term": {
"_EmailAddress_.keyword": {
"value": "test@test.com"
}
}
}
}
Examples of usage
Without pre-initialized mapper
var gq = new GridifyQuery()
{
Filter = "FirstName=John",
Page = 1,
PageSize = 20,
OrderBy = "Age"
};
var response = await client.SearchAsync<User>(s => s
.Index("users")
.ApplyPaging(gq)
.ApplyFiltering(gp)
.ApplyOrdering(gp));
return response.Documents;
GET users/_search
{
"query": {
"term": {
"firstName.keyword": {
"value": "John"
}
}
},
"from": 0,
"size": 20,
"sort": [{
"age": {
"order": "asc"
}
}]
}
With custom mapping
var gq = new GridifyQuery()
{
Filter = "name=John, surname=Smith, age=30, totalOrderPrice=45",
Page = 1,
PageSize = 20,
OrderBy = "Age"
};
var mapper = new GridifyMapper<User>()
.AddMap("name", x => x.FirstName)
.AddMap("surname", x => x.LastName)
.AddMap("age", x => x.Age)
.AddMap("totalOrderPrice", x => x.Order.TotalSum);
var response = await client.SearchAsync<User>(s => s
.Index("users")
.ApplyFilteringOrderingPaging(gq));
return response.Documents;
GET users/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"firstName.keyword": {
"value": "John"
}
}
},
{
"term": {
"lastName.keyword": {
"value": "Smith"
}
}
},
{
"term": {
"age": {
"value": 30
}
}
},
{
"term": {
"order.totalSum": {
"value": 45
}
}
}
]
}
},
"from": 0,
"size": 20,
"sort": [{
"age": {
"order": "asc"
}
}]
}
With CustomElasticsearchNamingAction initialized
By default, Elasticsearch converts property names to camel-case for document fields. That's Gridify.Elasticsearch extensions work by default. But if it's necessary to apply a custom naming policy, it can also be customized.
Func<string, string>? namingAction = p => $"_{p}_";
var mapper = new GridifyMapper<TestClass>(autoGenerateMappings: true)
{
Configuration = { CustomElasticsearchNamingAction = namingAction }
};
var gq = new GridifyQuery()
{
Filter = "FirstName=John",
Page = 1,
PageSize = 20,
OrderBy = "Age"
};
var response = await client.SearchAsync<User>(s => s
.Index("users")
.ApplyFilteringOrderingPaging(gq));
GET users/_search
{
"query": {
"term": {
"_FirstName_.keyword": {
"value": "John"
}
}
},
"from": 0,
"size": 20,
"sort": [{
"_Age_": {
"order": "asc"
}
}]
}
WARNING
Gridify.Elasticsearch package does not support all of the advanced Gridify features like NestedFiltering