Помогите с запросом

26 views
Skip to first unread message

Евгений Тимощук

unread,
Dec 9, 2013, 8:07:47 AM12/9/13
to mongodb-us...@googlegroups.com
Есть следующая структура:

[
{
id: 1,
                ...
data: {
                        ...
sids: [
{
id: 11,
                                        ...
countries: [
{
id: 'UA',
count: 4
},
{
id: 'RU',
count: 2
}
]
},
{
id: 12,
                                        ...
countries: [
{
id: 'RU',
count: 3
}
]
},
...
]
}
},
...
]

Необходимо получить сумму "data.sids[x].countries[y].count" для всех стран, где "data.sids[x].countries[y].id" = "UA".

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

Пока написал так, но выборка в 14 секунд никак не устраивает:

db.data.mapReduce(
function() {
var sids = this.data.sids, i = sids.length;
while (i--) {
var countries = sids[i].countries, j = countries && countries.length || 0;
while (j--) {
emit('count', countries[j].count);
}
}
},

function(key, values) {
return Array.sum(values);
},

{out: 'count'}
)

Serge Matveenko

unread,
Dec 9, 2013, 8:29:20 AM12/9/13
to mongodb-us...@googlegroups.com
Предрассчитывать сумму в документ в поле data.sids_count, а дальше
а. Делать map/reduce, но уже по одному полю.
б. Использовать aggregation framework для ее подсчета.
в. Выбирать все нужные суммы и считать программно.

Вариант 2
Попробовать оптимизировать свой map/reduce: использовать forEach и Array.sum.



2013/12/9 Евгений Тимощук <gans...@gmail.com>:
> --
> You received this message because you are subscribed to the Google Groups
> "MongoDB по-русски" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mongodb-user-rus...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.



--
Serge Matveenko
mailto: se...@matveenko.ru
github: http://lnkfy.com/1
linkedin: http://lnkfy.com/S

Евгений Тимощук

unread,
Dec 9, 2013, 8:56:35 AM12/9/13
to mongodb-us...@googlegroups.com
Это вариант, но помимо "count" - есть еще множество параметров, по которым могут быть различного вида агрегации. Так что второй вариант -  получается единственный.

Serge Matveenko

unread,
Dec 9, 2013, 9:09:02 AM12/9/13
to mongodb-us...@googlegroups.com
2013/12/9 Евгений Тимощук <gans...@gmail.com>:
> Это вариант, но помимо "count" - есть еще множество параметров, по которым
> могут быть различного вида агрегации. Так что второй вариант - получается
> единственный.

Если запросы не генерируются динамически, то их количество конечно, а
значит количество предрассчитаных полей тоже конечно.

Еще можно посмотреть в сторону `out: reduce`
http://docs.mongodb.org/manual/reference/command/mapReduce/#mapreduce-out-cmd

Евгений Тимощук

unread,
Dec 9, 2013, 9:43:56 AM12/9/13
to mongodb-us...@googlegroups.com
Именно динамически.
А индексы если построить, может как то помочь?

Serge Matveenko

unread,
Dec 10, 2013, 1:24:45 AM12/10/13
to mongodb-us...@googlegroups.com
Индексы по полям выборки помогут, чтобы быстрее выбирать срез
коллекции для map/reduce по нему. В самом map/reduce не помогут.

А, кстати, показали бы explain.


On Mon, Dec 9, 2013 at 6:43 PM, Евгений Тимощук <gans...@gmail.com> wrote:
> Именно динамически.
> А индексы если построить, может как то помочь?
>
> --
> You received this message because you are subscribed to the Google Groups
> "MongoDB по-русски" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to mongodb-user-rus...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.



Reply all
Reply to author
Forward
0 new messages