Skip to content

Instantly share code, notes, and snippets.

@Yegoroff
Last active November 1, 2022 16:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yegoroff/5327726 to your computer and use it in GitHub Desktop.
Save Yegoroff/5327726 to your computer and use it in GitHub Desktop.
Generating PlainElastic.Net query builder using ElasticSearch JSON query as pattern.
{
"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
}
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.
}
}
}
@jugal92
Copy link

jugal92 commented Dec 9, 2014

QueryBuilder is a predefined class in NEST or You have created it ?..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment