Elasticsearch - Nest - 'Range' query on 'string' - elasticsearch

Can you do a range query on a string still using nest in the lastest 2.0 alpha release? Or has this been dropped in elasticsearch.
Documentation -- suggests it is still in Elasticsearch itself
however
Range -- seems to only accept 'double'.
E.g.
...
(sh => sh.Range(ra => ra.Field(of =>
of.Name).LessThanOrEquals(
!string.IsNullOrEmpty(textInputName)
? textInputName.ToString(): null
))
...
Used to work in 1.7 Nest, but now says the input for LessThanOrEquals must be a double.
How do I now get everything where 'name' is between, for example, 'a' and 'f'?
Edit:
I think it was removed here in file src/Nest/QueryDsl/TermLevel/Range/RangeQuery.cs... just can not find 'why'.... :S

Range queries on string fields are now in the alpha2 release on nuget
(sh => sh
.TermRange(ra => ra
.Field(of => of.Name)
.LessThanOrEquals(!string.IsNullOrEmpty(textInputName)
? textInputName.ToString()
: null)
)

Related

Running DateRange with null values on ElasticSearch?

I am writing some queries in my ElasticSearch project that can be filtered by Date. I have written them like this:
var searchResponse = client.Search<mdl.Event>(s => s
.Query(q => q
.QueryString(qs => qs
.Query(search.Space))
&& q
.DateRange(r => r
.Field(f => f.CreatedTimeStamp)
.GreaterThanOrEquals(search.From)
.LessThanOrEquals(search.To))));
However, search.From and search.To are optional inputs, so they might turn out to be null. In the event that they are null, does this break the query? Or will it continue as if the DateRange part of the query is not included?
Nest queries are condition less. If input is determined to be null or empty string then the query will be omitted from the request.
So you don't need to check whether each filter property is null , NEST will perform this filtering by default.
In your case if search.From and search.To are null then range check will be removed from final query

Using Elasticsearch Nest 7.x to query 5.x index

I have a project using Nest 7.x and there is a query I need to make to an older 5.x elasticsearch index. When I make a call like this, I get the following error. I am guessing it is due to how the mapping types were changed in version 6 and greater. Is there any way around this to query an older index?
var result = _elasticClient.GetAsync<Category>(id)
Invalid NEST response built from a successful (404) low level call on
GET: /myindex/_doc/15437
Request: <Request stream not captured or already read to completion by serializer. Set DisableDirectStreaming() on ConnectionSettings to
force it to be set on the response.>
Response: {"_index":"2020-01-13","_type":"_doc","_id":"15437","found":false}
As a workaround, I did this and it appears to work. Not sure if there are any better solutions?
var response = _elasticClient.SearchAsync<Category>(s => s
.Query(q => q
.Bool(b => b
.Must(
bs => bs.Term(p => p.Id, id),
bs => bs.Term(p => p.Field("_type").Value("category"))
)
)
)
)

ElasticSearch NEST multi match returns all result

I have this C# code which is expected to match 2 fields using multi-match Elastic Search type. I am using NEST package.
var response = await _elasticClient.SearchAsync<FileDocument>(
s => s.Query(q => q.MultiMatch(c => c
.Fields(f => f.Field(p => p.FileName).Field(query))
.Fields(f => f.Field(p => p.Metadata).Field(query))
)));
Problem is no matter what text I passed in, it returns all the result. Anything I miss out?
In order to efficiently debug these types of issue, you need to inspect the HTTP request going to Elasticsearch, ultimately your query builder will be converted to search JSON and will be executed against Elasticsearch.
I am not aware of nest but have written the answer for Java code, which prints the Elasticsearch query in JSON format.
Although my guess is that, you are not sending the correct HTTP method which should be POST and you might be sending it with GET, which is causing ES to ignore your search query and return all documents.
Solved after adding .Query(query)
var response = await _elasticClient.SearchAsync<FileDocument>(
s => s.Query(q => q.MultiMatch(c => c
.Fields(f => f.Field(p => p.FileName).Field(p=>p.Metadata))
.Query(query)
))
);
Reference - https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/multi-match-usage.html

Elastic Search Date Range Filter lambda expression issue

Using Nest for ElasticSearch. enter image description here
part of the index looks like this "startdate" : "2018-11-01T00:00:00", "enddate" : "2018-11-01T00:00:00"
My fluentAPI query looks like below
var response = client.Search<ActivityReportsSearchViewModel>(x => x
.Size(500)
.Query(q => q.Bool(b => b.Must
(mu => mu.MultiMatch(m => m
.Fields(n => n.Fields(f => f.User, f => f.Activity
, f => f.County, f => f.Constituency, f => f.Country
, f => f.ActivityRequestDescription, f => f.ActivityDescription,
f => f.LessonsLearnt, f => f.Challenges, f => f.Recommendatinons, f => f.User
, f => f.Venue, f => f.Division))
.Query(**search**)))
.**Filter**(fi => fi
.DateRange(r => r
.Field(f => f.StartDate)
.GreaterThan("2018-08-20")
.LessThanOrEquals(DateMath.Now)
)))));
The query runs well and return results WITHOUT filter. After I add filter as shown above the query returns no results. Can anyone point the problem with the fluentAPI code
You can check response.IsValid to determine whether the request is valid for the API call to Elasticsearch.
The response.DebugInformation will provide more details about the API call in a friendly to read format, including if there is an error. If it is an error in Elasticsearch, response.ServerError will be populated with the details.
Without knowing further details about the response, I suspect the problem is an issue with parsing the string "2018-08-20" as a date on the Elasticsearch server side. Elasticsearch will attempt to parse the string into a date using the format specified in the date field mapping for StartDate, and if the date in the search request is in a different format, you can supply the format in the DateRange query with .Format(...).
Assuming that the document was originally indexed with the .NET client and the default DateTime serialization was used, you should just be able to use an instance of DateTime to supply the needed date
.DateRange(r => r
.Field(f => f.StartDate)
.GreaterThan(new DateTime(2018, 8, 20))
.LessThanOrEquals(DateMath.Now)
)
which will serialize as
"2018-08-20T00:00:00"
which is the same format as the field in the index. Alternatively, you can pass the string in this format.

ElasticSearch aggregation returns always 10 buckets only

I am using NEST. The number of buckets returned from ElasticSearch aggregation is always 10 (default value), in spite of the fact that the size is set to 10000
You need to set the size inside the Terms aggregation and not outside of it. Try this:
.Aggregations( a => a
.Terms(category_agg", st => st
.Field(o => o.categories.Select(x => x.id))
.Size(10000)
)
)

Resources