Last active
November 1, 2022 16:12
-
-
Save Yegoroff/5327726 to your computer and use it in GitHub Desktop.
Generating PlainElastic.Net query builder using ElasticSearch JSON query as pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"query": { | |
"bool": { | |
"must": [ | |
{ "query_string": { | |
"default_field": "FullName", | |
"query": "Jonh Doe" | |
}}, | |
{ "query_string": { | |
"default_field": "BusinessName", | |
"query": "Mr. Doe" | |
}}, | |
{ "query_string": { | |
"default_field": "Job", | |
"query": "President" | |
}}, | |
{ "query_string": { | |
"default_field": "Description", | |
"query": "keywords" | |
} } | |
] | |
} | |
}, | |
"filter": { | |
"bool": { | |
"must": [ | |
{ "term": { "IsPublic": "True" } }, | |
{ "term": { "PathLocationIDs": "NY" } }, | |
{ "terms": { "Industries": [ "Food", "Clothing" ] } } | |
{ "terms": { "Languages": [ "English", "Spanish" ] } } | |
] | |
} | |
}, | |
"facets": { | |
"PathLocations": { | |
"terms": { | |
"all_terms": true, | |
"field": "PathLocations", | |
"size": 50 | |
} | |
}, | |
"IndustryIDs": { | |
"terms": { | |
"field": "IndustryIDs", | |
"size": 50 | |
} | |
}, | |
"ContactTypeIDs": { | |
"terms": { | |
"field": "ContactTypeIDs", | |
"size": 50 | |
} | |
} | |
}, | |
"from": 10, | |
"size": 20 | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using PlainElastic.Net; | |
using PlainElastic.Net.Queries; | |
using PlainElastic.Net.Serialization; | |
namespace ConsoleApplication1 | |
{ | |
public class Person | |
{ | |
public string FullName { get; set; } | |
public string BusinessName { get; set; } | |
public string Job { get; set; } | |
public string Description { get; set; } | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
string query = BuildQuery(startIndex: 10, pageSize: 20, name: "Jonh Doe", businessName: "Mr. Doe", | |
job: "President", keywords: "keywords", locationID: "NY", | |
industries: new[] {"Food", "Clothing"}, languages: new[] {"English", "Spanish"}); | |
Console.WriteLine("Generated JSON Query:"); | |
Console.WriteLine(query); | |
var connection = new ElasticConnection(); | |
var serializer = new JsonNetSerializer(); | |
string queryResults = connection.Post(Commands.Search(index: "persons_index", type: "person_type"), query); | |
Console.WriteLine("Returned JSON Results:"); | |
Console.WriteLine(queryResults); | |
SearchResult<Person> foundPersons = serializer.ToSearchResult<Person>(queryResults); | |
Console.WriteLine("Found Persons:"); | |
foreach (var person in foundPersons.Documents) | |
{ | |
Console.WriteLine(person.FullName); | |
} | |
Console.ReadKey(); | |
} | |
static string BuildQuery(int startIndex, int pageSize, | |
string name, string businessName, string job, string keywords, | |
string locationID, string[] industries, string[] languages) | |
{ | |
var query = new QueryBuilder<Person>() | |
.From(startIndex) | |
.Size(pageSize) | |
.Query(q => q | |
// You can't combine several QueryString queries by just listing them. You need some query that groups them, like Bool query. | |
.Bool(b => b | |
.Must(m => m | |
.QueryString(qs => qs.DefaultField(person => person.FullName).Query(name)) | |
.QueryString(qs => qs.DefaultField(person => person.BusinessName).Query(businessName)) | |
.QueryString(qs => qs.DefaultField(person => person.Job).Query(job)) | |
.QueryString(qs => qs.DefaultField(person => person.Description).Query(keywords)) | |
) | |
) | |
) | |
.Filter(f => f | |
.Bool(b => b | |
.Must(m => m | |
// do these fields (IsPublic, PathLocationIDs, Industries, Languages) belong to the Person type? | |
// why don't you use .Term(t => t.Field(person => person.IsPublic).Value("True")) instead? | |
.Term(t => t.Field("IsPublic").Value("True")) | |
.Term(t => t.Field("PathLocationIDs").Value(locationID)) | |
// note that by default ES lowercased all values and requires query be in lowercase, | |
// so you should use something like: industries.Select(i => i.ToString().ToLower()) | |
.Terms(t => t.Field("Industries").Values(industries.Select(i => i.ToString())) ) | |
.Terms(t => t.Field("Languages").Values(languages.Select(i => i.ToString())) ) | |
) | |
) | |
) | |
.Facets(facets => facets | |
.Terms(t => t.AllTerms(true).FacetName("PathLocations").Field("PathLocations").Size(50)) | |
.Terms(t => t.FacetName("IndustryIDs").Field("IndustryIDs").Size(50)) | |
.Terms(t => t.FacetName("ContactTypeIDs").Field("ContactTypeIDs").Size(50)) | |
); | |
return query.BuildBeautified(); //You can use .Build(); to create more compact query JSON. | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
QueryBuilder is a predefined class in NEST or You have created it ?..