2015-01-13 7 views
1

У меня есть коллекция MongoDB, в которой каждый из устройств хранит измерения в массивах для различных физических параметров - например, разных напряжений, температур и т. Д., Но которые не являются общие и предсказуемые для каждого. Пример:

{ 
    device_id: 1, 
    measurements: 
    { 
    parameter_one: 
    [ 
     {measurement object #1}, {measurement object #2}, ... {measurement object #n} 
    ], 
    parameter_two: 
    [ 
     {measurement object #1}, {measurement object #2}, ... {measurement object #m} 
    ], 
    ... 
    } 
}, 
{ 
    device_id: 2, 
    measurements: 
    { 
    parameter_one: 
    [ 
     {measurement object #1}, {measurement object #2}, ... {measurement object #l} 
    ], 
    parameter_three: 
    [ 
     {measurement object #1}, {measurement object #2}, ... {measurement object #k} 
    ] 
    } 
} 

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

Я знаю, как справиться с этой структурой после того, как я вернул ее с помощью .find() или .findOne(), итерацией по структуре JSON измерения с использованием чистого JavaScript.

Вот где мне нужно помощь: После того, как эти массивы параметров вырасти до значительных размеров, я только на самом деле хочу, чтобы отрезать последние несколько сот каждый из их элементов в моей находке() или findOne(), а не вернуть всю запись устройства, а затем перебрать и отрезать их, если большая часть записи устройства не имеет значения.

Но, как указано, я не могу просто сказать $slice: {measurements.parameter_key: -N}, потому что я не знаю, априори, что это за параметры parameter_key для любой записи устройства. Есть ли способ в запросе Mongo для итерации по неизвестным вложенным документам и применения $ slice к каждому из них без указания ключа каждого массива, который нужно нарезать?

ответ

0

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

{ 
    "_id" : ObjectId(...), 
    "device_id" : 1, 
    "parameter" : "parameter_one", 
    "measurement" : { // measurement object - whatever this looks like }, 
    "date" : ISODate(...) 
} 

Чтобы найти эквивалент последних нескольких сот записей массива измерений для устройства, индекс { "device_id" : 1, "date" : -1 }, затем сортировать по убыванию date и ограничение использования:

db.measurements.find({ "device_id" : 1 }, { "date" : -1 }).limit(691) 

трудно знать, если это полезно изменить для вас от того, что вы описали в случае использования, хотя. Почему вы не знаете, что измеряет данное устройство? Что вы делаете с таинственными измерениями, которые устройство может или не может произвести? Каким будет использование последних нескольких сотен записей для параметра тайны для определенного устройства? Возможно, я смогу улучшить ответ с дополнительной информацией. Возможно, вам придется запросить параметры, захваченные данным устройством, а затем использовать эту информацию для запроса необходимой информации.

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

+0

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

+0

Кстати, причина, по которой я не знаю, какие параметры устройства измеряют, заключается в том, что она полностью зависит от кода C++, который пользователи будут компилировать и загружать на устройство, и с которым я не контролирую. Независимо от того, какие параметры объявлены и переданы из этого кода на C++, необходимо автоматически вводить базу данных в качестве нового типа параметра. – msolters

Смежные вопросы