我有以下型号
public class Ticket
{
public string Id { get; set; }
public string Question { get; set; }
public DateTime CreateDate { get; set; }
public DateTime ClosedDate { get; set; }
public int Votes { get; set; }
}
我正在使用ElasticSearch Nest客户端搜索票证,其中任何字段包含日期范围内的特定文本。
我尝试了以下操作:
var result = client.Search<Ticket>(
s => s.Query(q =>
q.Bool(b =>
b.Must(ms => ms.QueryString(qs => qs.Query(term)))
.Filter(f =>
f.Bool(bb =>
bb.Must(ms => ms.DateRange(dr => dr.GreaterThanOrEquals(from).LessThanOrEquals(to))
))))));
无论指定时间如何,它都会返回所有票证。
它还只在我要搜索文本中单词的任何部分时才搜索完整的单词。
有什么想法吗?
答案 0 :(得分:1)
对于DateRange
查询,需要使用Field
值来使Elasticsearch中的字段运行。如果没有为此提供值,则NEST会认为查询是无条件的,并且不会将其序列化为已发送查询的一部分。
例如,给定
var term = "term";
var to = DateTime.Now;
var from = to.AddDays(-7);
您当前的查询序列化为
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "term"
}
}
]
}
}
}
如果添加了Field
var result = client.Search<Ticket>(s => s
.Query(q => q
.Bool(b => b
.Must(ms => ms
.QueryString(qs => qs
.Query(term)
)
)
.Filter(f => f
.Bool(bb => bb
.Must(ms => ms
.DateRange(dr => dr
.Field(df => df.CreateDate)
.GreaterThanOrEquals(from)
.LessThanOrEquals(to)
)
)
)
)
)
)
);
现在序列化为
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "term"
}
}
],
"filter": [
{
"bool": {
"must": [
{
"range": {
"createDate": {
"gte": "2018-07-17T12:20:02.8659934+10:00",
"lte": "2018-07-24T12:20:02.8659934+10:00"
}
}
}
]
}
}
]
}
}
}
使用operator overloading on queries,可以更简洁地编写
var result = client.Search<Ticket>(s => s
.Query(q => q
.QueryString(qs => qs
.Query(term)
) && +q
.DateRange(dr => dr
.Field(df => df.CreateDate)
.GreaterThanOrEquals(from)
.LessThanOrEquals(to)
)
)
);
序列化为
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "term"
}
}
],
"filter": [
{
"range": {
"createDate": {
"gte": "2018-07-17T12:21:50.2175114+10:00",
"lte": "2018-07-24T12:21:50.2175114+10:00"
}
}
}
]
}
}
}