Поиск DateRange не работает в эластичном поиске NEST API - PullRequest
0 голосов
/ 03 июля 2019

У меня есть таблица записей журналов, и я хочу провести простой поиск по дате.

Например, я хотел выполнить поиск по всем запросам до 01.06.2019 00:00:00 (mm.DD.yyyy чч: мм: сс) и написал этот запрос:

var query = client.Search<SearchEventDto>(s => s
                .AllIndices()
                .AllTypes()
                .Query(q => q
                    .MatchAll() && +q
                    .DateRange(r =>r
                        .Field(f => f.timestamp)
                        .LessThanOrEquals(new DateTime(2019,06,01, 0, 0, 0))
                    )
                )
            ); 

Мой Dto выглядит так:

 public class SearchEventDto : IDto
    {
        [KendoColumn(Hidden = true, Editable = true)]
        public string id { get; set; }

        [KendoColumn(Order = 2, DisplayName = "Level")]
        public string level { get; set; }
        [KendoColumn(Order = 4, DisplayName = "Message")]
        public string message { get; set; }

        [KendoColumn(Hidden = true)]
        public string host { get; set; }
        [KendoColumn(Order = 3, DisplayName = "Source")]
        public string src { get; set; }

        [KendoColumn(Order = 1, DisplayName = "Timestamp", UIType = UIType.DateTime)]
        public DateTime timestamp { get; set; }

        [KendoColumn(Hidden = true)]
        public DateTime time { get; set; }

    }

К сожалению, он возвращает все записи, ничего не фильтруя. Куда я в этом ошибаюсь?

Заранее спасибо!

PS: версия ES: 6.7.0, NEST: 6.8

PS: я интегрировал журналы с Nlog. Итак, теперь каждый день он вставляет новый индекс с датой в качестве имени. Вот отображение для 219-06-28 (я использую @timestamp):

{
    "logstash-2019-06-28": {
        "mappings": {
            "logevent": {
                "properties": {
                    "@timestamp": {
                        "type": "date"
                    },
                    "host": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "level": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "message": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "src": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "time": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    }
                }
            }
        }
    }
}

1 Ответ

2 голосов
/ 03 июля 2019

Я опубликую то, что мы выяснили, в комментариях в качестве ответа, поскольку я думаю, что есть пара вещей, которые можно улучшить, чтобы повысить производительность и удобочитаемость.

Решение:

Запрос из вопроса использовал .Field(f => f.timestamp), который был переведен NEST для использования timestamp поле, а не @timestamp. Простое изменение на .Field("@timestamp") решит проблему, так как это правильное имя поля в отображении индекса.

{
    "logstash-2019-06-28": {
        "mappings": {
            "logevent": {
                "properties": {
                    "@timestamp": {
                        "type": "date"
                    },
                    ..
                }
            }
        }
    }
}

Мы также можем пометить свойство timestamp атрибутом PropertyName, чтобы сообщить NEST, что имя @timestamp будет использоваться вместо timestamp

 public class SearchEventDto : IDto
    {
        [KendoColumn(Order = 1, DisplayName = "Timestamp", UIType = UIType.DateTime)]
        [PropertyName("@timestamp")]
        public DateTime timestamp { get; set; }

    }

и запрос

var query = client.Search<SearchEventDto>(s => s
                .AllIndices()
                .AllTypes()
                .Query(q => q
                    .MatchAll() && +q
                    .DateRange(r =>r
                        .Field(f => f.timestamp)
                        .LessThanOrEquals(new DateTime(2019,06,01, 0, 0, 0))
                    )
                )
            ); 

будет просто работать.

Улучшения:

Запрос только конкретных индексов:

var query = client.Search<SearchEventDto>(s => s
        .AllIndices()
        .AllTypes()
        ..

Используя AllIndices(), мы сообщаем упругому поиску, чтобы попытаться собрать документы по всем индексам, мы могли бы немного изменить его, чтобы запрашивать только индексы с данными журналов:

var query = client.Search<SearchEventDto>(s => s
                .Index("logstash-*")
                .Type("logevent")
                ..

Использовать контекст фильтра для фильтра диапазона дат:

.Query(q => q.Bool(b => b.Filter(f => f.DateRange(..))))

Таким образом, ваш запрос должен быть быстрее, так как он не заботится о расчете показателя релевантности поиска. Подробнее об этом можно прочитать здесь .

Надеюсь, это поможет.

...