пятница, 14 января 2022 г.

Mongo: Aggregation with Pagination

Допустим у нас есть такая коллекция users в Mongo DB:
[
  {
    username: "john.doe",
    roles: ["user"],
    contacts: [
      {
        name: "John Doe",
        email: "johndoe@gmail.com"
      },
      {
        name: "J.D.",
        email: "jd@gmail.com",
        phone: "+11111111111"
      }
    ]
  },
  {
    username: "jack.sparrow",
    roles: ["manager"],
    contacts: [
      {
        name: "Jack Sparrow (gmail)",
        email: "jack.sparrow@gmail.com",
      },
      {
        name: "Jack Sparrow (hotmail)",
        email: "jack.sparrow@hotmail.com",
      }
    ]
  }
]

И мы хотим организовать просмотр всех контактов всех пользователей в одной таблице с разбивкой по страницам ("pagination"). То есть так:


Чтобы получить все контакты можно воспользоваться aggregation с $unwind.

Еще нам нужно посчитать количество всех контактов, после чего "вырезать" только те, которые нужно показать в выбранной странице. Для того, чтобы выполнить обе эти операции одним запросом, воспользуемся чудесной пайплайн-стадией $facet. Получится так:
db.collection('users').aggregate([
  {"$unwind":"$contacts"},
  {"$facet":{
    "meta":[
      {"$count": "totalCount"}
    ],
    "data":[
      {"$sort":{'contacts.name':1,'username':1}},
      {"$skip":firstRow-1},
      {"$limit":page_size},
      {"$replaceRoot":
        {"newRoot":{
          "$mergeObjects":[
            {
              "username":"$username",
            },
            "$contacts"
          ]
        }}
      },
    ],
  }},
]);
page_size - это количество записей на странице.
firstRow - это номер первой записи на странице. Вычисляется он так:
const firstRow = (page > 0 ? ((page-1) * page_size) : 0) + 1;
Вместо $unwind могут быть другие пайплайн-стадии, которые выбирают нужные для показа данные. Основной же прием, который я хотел продемонстрировать в этом посте, - это использование $facet.

Полный пример можно посмотреть на github:
===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru

четверг, 13 января 2022 г.

ShellIconOverlayIdentifiers (windows 10)

Забавная вещь в Windows 10: ShellIconOverlayIdentifiers


О том что это такое можно почитать в документации Microsoft: https://docs.microsoft.com/en-us/windows/win32/shell/how-to-register-icon-overlay-handlers

А забавно тут вот что: есть лимит на количество "обработчиков наложения значков" (icon overlay  handlers), который равен 15. Выбираются первые (по алфавиту) 15 обработчиков, остальные игнорируются. Поэтому ушлые разработчики софта, которые желают, чтобы их обработчики шли первыми в списке и работали, начали добавлять в начале имени пробелы (см. скриншот). Кто больше пробелов добавит, тот и молодец :) Интересно, кто-нибудь уже додумался при установке  приложения проверять существующие обработчики на предмет наличия в них пробелов в начале, и делать в своих на один больше? 

===
Перепечатка материалов блога разрешается с обязательной ссылкой на blog.coolsoftware.ru