Временной ряд MongoDB для истории процесса: запрос по разным байтам поля _id - PullRequest
0 голосов
/ 02 мая 2018

Я хочу хранить данные временных рядов в mongodb. Я знаю, я знаю, в сети есть много статей об этом, но ни одна не предложила решение именно моей проблемы, и многие из них ссылаются на старый механизм хранения mmap, и я использую WiredTiger, и многие из них иметь дело с равноотстоящими временными рядами. Цель состоит в том, чтобы достичь наилучшего компромисса между пропускной способностью чтения и записи, одновременно обеспечивая максимальную масштабируемость (даже до терабайт данных временных рядов) и минимальный размер дискового хранилища / потребление оперативной памяти. Это также означает минимальное количество индексов. Историк должен иметь возможность импортировать прошлые данные, поэтому новые данные не всегда добавляются с увеличением отметки времени. Я уже разработал минималистичную схему:

{
    "_id": "f061e95ae4dc281aea4df2f8",
    "Values": [
        {
            "Time": "2018-05-02T07:56:40.545Z",
            "Value": "529"
        },
        {
            "Time": "2018-05-02T07:56:51.119Z",
            "Value": "254"
        },
...
    ]
}

Этот документ представляет один блок данных, который принадлежит одному сигналу, и один час времени (данные будут иметь наименьшее, но неэквидистантное время выборки около 1 секунды). Коллекция содержит только документы, подобные этому, и имеет только один индекс (конечно, на _id). _Id документа генерируется на основе хеша уникального идентификатора этого сигнала и начала утечек, к которым принадлежит блок данных.

Как видите, для запроса данных я вычисляю набор идентификаторов на основе заданного временного диапазона и идентификатора сигнала. Первые 4 байта _id кодируют час работы, последние 8 байтов хэш идентификатора сигнала. Следовательно, запрос, запрашивающий один день данных одного сигнала, приведет к тому, что запрос попытается получить 24 идентификатора. Проблема заключается в том, что для больших временных диапазонов (например, начиная с эпохи до настоящего времени) мне приходится запрашивать множество идентификаторов (например, 400000), что, кажется, делает запрос довольно медленным. (Сокращенный) запрос базы данных mongodb (в C #):

FilterDefinition<DBTimeSeries> f = Builders<DBTimeSeries>.Filter.Empty;
var filterbuilder = Builders<DBTimeSeries>.Filter;
IEnumerable ids = Helpers.GetIDs(start, end, tagname);
var f = Builders<DBTimeSeries>.Filter.Empty;
f = f & filterbuilder.In(x => x.ID, ids);
var chunks = await collection.FindAsync<DBTimeSeries>(f);

Даже при небольшом объеме данных в базе данных этот запрос может занять до одной минуты. Свойство ID имеет тип "ObjectId" из драйвера C # mongodb.

Я знаю, что это возможно

f = f & filterbuilder.Where(x => x.ID > new ObjectId(DateTime.Now.AddDays(-1), 0, 0, 0) && x.ID < new ObjectId(DateTime.Now, 0, 0, 0))

, что означает, что я могу выполнять запросы временных диапазонов по идентификаторам, но это не дает мне возможности запрашивать данные для одного конкретного сигнала без добавления дополнительного поля к документу, представленному выше. Мне бы даже пришлось проиндексировать это поле для лучшей производительности.

Поэтому мой вопрос: было бы оптимально иметь возможность запрашивать _id с помощью запроса типа: «Дайте мне документы, первые 4 байта поля _id которых представляют собой uint32 между x и y и последние 8 байтов Поле _id равно заданному unit64 ". В запросе должны использоваться исключительно индексы, что должно быть возможно, поскольку вся информация хранится в поле _id. Я знаю о параметре $ bitsAllSet (https://docs.mongodb.com/manual/reference/operator/query/bitsAllSet/#op._S_bitsAllSet),, но я могу каким-то образом передать только long в драйвере C #, и запросы, похоже, не могут использовать индекс для части запроса $ bitsAllSet ...

У кого-нибудь есть идея? Спасибо всем заранее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...