Skip to content

Instantly share code, notes, and snippets.

@robertlyson
Last active February 9, 2017 19:51
Show Gist options
  • Save robertlyson/a191a1653634720f9ce94fdb75a0aade to your computer and use it in GitHub Desktop.
Save robertlyson/a191a1653634720f9ce94fdb75a0aade to your computer and use it in GitHub Desktop.
using System;
using Elasticsearch.Net;
using Nest;
namespace PercolateQuery
{
public static class Program
{
static string dateFormat = "dd/MM/yyyy";
static void Main()
{
var setting = new ConnectionSettings(new Uri("http://localhost:9200"));
var defaultIndex = "testindex";
setting.DefaultIndex(defaultIndex).DisableDirectStreaming();
var elasticClient = new ElasticClient(setting);
var deleteIndexResponse = elasticClient.DeleteIndex(defaultIndex);
var createIndexResponse = elasticClient.CreateIndex(defaultIndex, c => c.Mappings(map => map
.Map<PercolatedQuery>(m => m
.AutoMap()
.Properties(p => p
.Percolator(pp => pp
.Name(n => n.Query)
)
))
.Map<Document>(m => m
.AutoMap()
.Properties(p => p
.Date(d => d.Name(n => n.Date).Format(dateFormat))))));
var indexResponse = elasticClient.Index<Document>(new Document
{
Name = "test",
Date = DateTime.Now.ToString(dateFormat)
}, d => d.Refresh(Refresh.WaitFor));
//so this date range query works like a charm, great
Func<QueryContainerDescriptor<Document>, QueryContainer> query = q => q
.DateRange(dr => dr
.Field(f => f.Date)
.GreaterThanOrEquals("now-3d")
.LessThanOrEquals("now"));
var searchResponse = elasticClient.Search<Document>(s => s.Query(query));
//now, I want to register percolator
var percolatorRegistrationResponse = elasticClient.Index<PercolatedQuery>(new PercolatedQuery
{
Id = "1",
Query = query(new QueryContainerDescriptor<Document>())
}, d => d.Refresh(Refresh.WaitFor));
/*I can't because:
# ServerError: ServerError: 400
Type: mapper_parsing_exception
Reason: "failed to parse" CausedBy:
"Type: illegal_argument_exception
Reason: "percolator queries containing time range queries based on the current time is unsupported""
..
"current time is unsupported"
It was working in ES 1.x but now it doesn't
https://github.com/elastic/elasticsearch/blob/master/modules/percolator/src/main/java/org/elasticsearch/percolator/PercolatorFieldMapper.java#L371
instead of registering percolator with current time expression, I'm translating it into actual date
e.g.
"now".ToActualDate() -> 9/2/2017
"now-3d".ToActualDate() -> 6/2/2017
This is why I was asking if NEST can do this out of hand :D
*/
//let's replace now with actual dates
Func<QueryContainerDescriptor<Document>, QueryContainer> queryWithActualDates = q => q
.DateRange(dr => dr
.Field(f => f.Date)
.GreaterThanOrEquals(DateTime.Now.AddDays(-3).ToString(dateFormat))
.LessThanOrEquals(DateTime.Now.ToString(dateFormat)));
//try to register new one
var secondAttempt = elasticClient.Index<PercolatedQuery>(new PercolatedQuery
{
Id = "1",
Query = queryWithActualDates(new QueryContainerDescriptor<Document>())
}, d => d.Refresh(Refresh.WaitFor));
//success
}
public class Document
{
public string Name { get; set; }
public string Date { get; set; }
}
public class PercolatedQuery
{
public string Id { get; set; }
public QueryContainer Query { get; set; }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment