@MongoDBRussian

Страница 223 из 342
Ilya
12.04.2018
07:04:30
Всем добрый день, подскажите с таким вопросом: Есть документ вида: { _id: ObjectID name: string ...., items: [ { name: string type: string size: int }, ... ] } как видно у него есть массив вложенных документов items, в нем могут быть несколько тысяч. как при выборке ограничить элементы в items? на сайте монги советуют использовать аггрегации, но с ними проблема начинается в том что необходимо испольховать skip и limit, и в этом случае запрос начинает работать очень медленно

Ilya
12.04.2018
07:07:54
в смысле вынести в коллекцию отдельную?

Javed
12.04.2018
07:08:49
Ну да, где он имеет ещё одну поля создателя и хранить там ай ди его

Google
Javed
12.04.2018
07:09:03
Я не спец, тоже учусь

Ilya
12.04.2018
07:10:56
да пагинацию

Yurii
12.04.2018
07:11:52
да пагинацию
и ты делаешь {$unwind: "items"}, а потом $skip и $limit?

Ilya
12.04.2018
07:13:34
нет $unwind не пробывал, если его сделать и отфильровать то в результате будут только те items которые попали в условие?

Yurii
12.04.2018
07:16:05
нет $unwind не пробывал, если его сделать и отфильровать то в результате будут только те items которые попали в условие?
ну я не знаю, как ты делаешь, тут же нет твоей агрегации. Вообще оно должно быть как-то так db.collection.aggregate([ {$match: {_id: someId}}, {$unwind: "items"}, {$skip: 0}, {$limit: 50} ])

ну понятно, что skip и limit это уже твои настройки пагинации

Ilya
12.04.2018
07:17:45
эээ дак что в этом случае дал unwind ?

Yurii
12.04.2018
07:18:57
эээ дак что в этом случае дал unwind ?
у нас появилось количество = длине массива items одинаковых документов (кроме поля items), у которых items - уникальный объект, а не массив

Ilya
12.04.2018
07:19:46
я наверно плохо сформулировал

есть документ у которого в items тысячи вложенных документов, мне надо вывести этот же документ но с чтобы в items остались только те корые удовлетворяют условию

Yurii
12.04.2018
07:22:42
тогда вместо $unwind - https://docs.mongodb.com/manual/reference/operator/aggregation/slice/

Google
Ilya
12.04.2018
07:25:04
nак пагинация и items никак не связанны - пагинация для документа всего а не для items,

items надо по фильтру отфитровать а не по кол-ву

Yurii
12.04.2018
07:25:57
ну тут ты сказал, что надо именно пагинацию ?

тебе надо пагинацию, что ты skip и limit используешь, или просто последние несколько штук?

да пагинацию

Ilya
12.04.2018
07:26:13
пагинацию для всего документа

я не говорил что для items

Yurii
12.04.2018
07:26:44
ну вопрос же был как раз за items

ладно, проехали

возвращайся тогда сюда: db.collection.aggregate([ {$match: some_criteria }, {$skip: skip_qty }, {$limit: limit_qty } {$project: { items: {$filter: { input: "$items" as: "item", cond: { do_some_cond_with_$$item } }}, project_all_need_fileds: 1 }} ]) https://docs.mongodb.com/manual/reference/operator/aggregation/filter/

в таком случае ты делаешь сначала пагинацию по документах, а потом фильтруешь внутринности items по переденным критериям

Ilya
12.04.2018
07:33:15
ок, спасибо сейчас попробую

в общем работает, но опять та же самая проблема как только добавляешь skip - сразу скорость запроса проседает =(

Dmitry
12.04.2018
08:15:42
Со скипом всегда проседает. Это инородное понятие для NoSQL. Индексы сделаны?

В теории если зададите критерии - скорость будет выше.

Т.е. если у вас есть итерационное или предсказуемое поле его можно сформировать и скорость вывода уведичится

Ilya
12.04.2018
08:19:07
Т.е. если у вас есть итерационное или предсказуемое поле его можно сформировать и скорость вывода уведичится
можно поподробнее? индексы сделаны на те поля по которым match делается я так понял что в аггрегациях skip всегда будет вносить задержку?

Dmitry
12.04.2018
08:20:31
Да. Всегда. Для моего скип - это инородное. Она сначала делает агрегацию, а потом ее пагинирует. А вот если в условия пгрегации засунуть к примеру инкриментальный ид - будет значительно быстрее. Тогда агрегация будет скажем с 0 до 10

* монги / мое го

Вообще готовые агрегации со скипом ведь тоже можно индексировать и хранить

Google
Dmitry
12.04.2018
08:21:55
Или кешировать редисом

Забудьте все что знали о реляции) агрегация - берет всегда весь массив документов. Дополнительная выборка - всегда + 1 операция

Ilya
12.04.2018
08:24:51
ну вообще мне просто не понятно было почему project вобычном find не может нормально отфильтровать подмассив документов

в find же скип быстро работает)

Yurii
12.04.2018
08:25:24
https://dzone.com/articles/fast-paging-with-mongodb один из вариантов сделать быстрее скип - .find({'_id'> last_id})

Dmitry
12.04.2018
08:25:47
ну вообще мне просто не понятно было почему project вобычном find не может нормально отфильтровать подмассив документов
Может. Почему. Просто там два запроса по факту. Субдокументы - отдельная коллекция

Ilya
12.04.2018
08:28:52
https://dzone.com/articles/fast-paging-with-mongodb один из вариантов сделать быстрее скип - .find({'_id'> last_id})
это к сожалению не подойдет в текущей постановке задачи

Может. Почему. Просто там два запроса по факту. Субдокументы - отдельная коллекция
Мы такую фишку сделали на функции js - типа сначала делаем запрос, а потом уже сам массив items фильтруем в js руками, и он работает очень быстро, но я хотел понять можно ли средствами самой монги обойтись без хранимых функций

yopp
12.04.2018
08:31:37
Если вы хотите skip/limit по вложенным документам с условием по вложенным документам — быстро не будет.

Dmitry
12.04.2018
08:32:59
Ни какая это не отдельная коллекция
Разве? Я думал иначе. Киньтесь ссылкой про субдокументы. Как они устроены. Буду овен. Признателен

Ilya
12.04.2018
08:33:29
Если вы хотите skip/limit по вложенным документам с условием по вложенным документам — быстро не будет.
стоп еще раз скип и лимит нужен по верхнему документу, по вложенным нужен только фильтр

Dmitry
12.04.2018
08:35:20
https://docs.mongodb.com/manual/core/document/
Спс. Видимо просмотрел

Peter
12.04.2018
08:35:58
Вопросик, возможно ли в Studio3t посмотреть реальное время выполнение агрегатки? Или в каком GUI это реально?

yopp
12.04.2018
08:35:58
Документ это сериализированные в BSON данные. Самый простой способ смотреть на документ как на хэш таблицу

Поддокумент это просто ключ значением которого является ещё один хеш

Или массив таких хэшей

Так как BSON массив это тоже документ, у которого ключ эквивалентен индексу элемента

Google
Nick
12.04.2018
08:38:04
стоп еще раз скип и лимит нужен по верхнему документу, по вложенным нужен только фильтр
возможно уже предлагали, но поддокументы фильтровать как вы хотите только через аггрегейш последовательностью unwind-match-group

Peter
12.04.2018
08:39:16
explain?
В Studio3t он не возвращает время выполнение

Ilya
12.04.2018
08:40:14
Тогда полностью сформулируйте задачу
Есть документы такие: { _id: ObjectID name: '1' items: [ { name: 'cвойство1' type: 'тип1' size: 10 }, { name: 'cвойство2' type: 'тип2' size: 20 }, { name: 'cвойство3' type: 'тип2' size: 0 }, ] }, ...., { _id: ObjectID name: '2' items: [ { name: 'cвойство1' type: 'тип1' size: 110 }, { name: 'cвойство2' type: 'тип2' size: 120 }, { name: 'cвойство3' type: 'тип2' size: 10 }, ] } Надо сделать запрос такой чтобы вытащить документы у кторых имя может быть одно из '1', '2', '10', и в items у них есть поддокументы у которых size > 10 Причем в ответе для найденных документов не надо выводить поддокументы которые условию size > 10 не удовлетворяют.

причему еще надо делать пагинацию

Admin
ERROR: S client not available

yopp
12.04.2018
08:42:43
Если вам на страницу нужно вывести фиксированное количество поддокументов, то как я уже сказал — быстро не будет. Если нужно вывести фиксированное количество документов, то skip/limit

yopp
12.04.2018
08:43:44
А, да. Для фильтра по вложенным документам, да

Ilya
12.04.2018
08:43:49
2 надо вывсети фиксированное кол-во документов, но если применять skip в агрегациях запрос начинает значительно

угу

$elementMatch
только 1 элемент берет

ой

Nick
12.04.2018
08:44:33
так в первом match в аггрегате указываете запрос с elementMatch и вашим услвоием по имени, а дальше как и выше unwind-match-group

и поверх skip-limit

Ilya
12.04.2018
08:45:28
да все правильно, просто если без скипа делать запрос то он несколько милисекунд а со скипом уже полсекунды

Nick
12.04.2018
08:46:14
если хотите быстро, от меняйте структуру данных так чтобы было просто их получать

иначе всегда будет медленно

yopp
12.04.2018
08:46:51
Я не очень понимаю в чем загвоздка

Google
yopp
12.04.2018
08:47:12
Если нужно выводить например 10 документов в которых есть хоть одно совпадение с поддокументом — это простая задача

Ilya
12.04.2018
08:47:31
ну я думаю что полсекунды на запрос - это проблема?

yopp
12.04.2018
08:48:18
Посмотрите в explain

Nick
12.04.2018
08:48:20
ну я думаю что полсекунды на запрос - это проблема?
дальше уже оффтоп фактически будет, но сейчас полсекунды, завтра секунда, через месяц 10 секунд, данных то больше становится

yopp
12.04.2018
08:48:39
Вероятно вам нужно сделать индекс по полю вложенного документа

В вашем случае по items.size

Ilya
12.04.2018
08:49:23
разве на скип как то повлияет создание индекса?

Nick
12.04.2018
08:49:26
кстати аггрегаты в 3.6 только ан первый match индекс юзают?

yopp
12.04.2018
08:49:45
разве на скип как то повлияет создание индекса?
Поваляет на скорость выборки документов.

Nick
12.04.2018
08:50:16
чет затупил, задача же позволяет сделать skip-limit сразу после первого матч

а уже после делать анвинды

Nick
12.04.2018
08:50:37
ну да

хотя стой

Ilya
12.04.2018
08:50:46
смотрите я могу выбрать без скипа 1000 элементов за 10 мс, а допустим выбрать 10 документов со скипом в 1000 займет уже полсекунды - это нормально поведение*?

Nick
12.04.2018
08:51:07
он просил чтобы те элементы массива у которых size>10 не выводились

yopp
12.04.2018
08:52:08
смотрите я могу выбрать без скипа 1000 элементов за 10 мс, а допустим выбрать 10 документов со скипом в 1000 займет уже полсекунды - это нормально поведение*?
Я ещё раз повторю: смотрите в explain с executionStats: 1 например. Там будет детальная информация о том на что уходит время.

он просил чтобы те элементы массива у которых size>10 не выводились
У меня было ощущение что в 3.6 что-то по этому поводу завезли уже

Страница 223 из 342