Как $ max работает с массивом объектов? - PullRequest
0 голосов
/ 12 сентября 2018

Возьмите пример коллекции с этими документами:

client.test.foo.insert_one({
    'name': 'clientA',
    'locations': [
        {'name': 'a', 'sales': 0, 'leads': 2}, 
        {'name': 'b', 'sales': 5, 'leads': 1}, 
        {'name': 'c', 'sales': 3.3, 'leads': 1}]})
client.test.foo.insert_one({
    'name': 'clientB',
    'locations': [
        {'name': 'a', 'sales': 6, 'leads': 1},
        {'name': 'b', 'sales': 6, 'leads': 3},
        {'name': 'c', 'sales': 1.3, 'leads': 4}]})

Как $ max определяет, какой элемент в массиве местоположений является максимальным?

client.test.foo.aggregate([{'$project': {'maxItem': {'$max': '$locations'}}}]))

Возвращает:

[{'_id': ObjectId('5b995d72eabb0f0d86dceda5'),
  'maxItem': {'leads': 1, 'name': 'b', 'sales': 5}},
 {'_id': ObjectId('5b995d72eabb0f0d86dceda6'),
  'maxItem': {'leads': 3, 'name': 'b', 'sales': 6}}]

Похоже, $max выбирает сортировку по sales, но я не уверен, почему?

1 Ответ

0 голосов
/ 12 сентября 2018

Я обнаружил это https://docs.mongodb.com/manual/reference/bson-type-comparison-order/#objects в котором говорится:

Для сравнения объектов BSON в MongoDB используется следующий порядок:

  1. Рекурсивно сравнивать пары ключ-значение в порядке их появления внутри объекта BSON.
  2. Сравнить ключевые имена полей.
  3. Если имена ключевых полей совпадают, сравните значения полей.
  4. Если значения полей равны, сравните следующую пару ключ / значение (возврат к шагу 1). Объект без дальнейших пар меньше чем объект с другими парами.

, что означает, что если sales является первым ключом в объекте bson, тогда у меня есть ответ. Я использую pymongo, и словари python не упорядочены, поэтому я перешел на bson.son.SON и повторил пример:

client.test.foo.delete_many({})
client.test.foo.insert_one({
    'name': 'clientA',
    'locations': [
        bson.son.SON([('name', 'a'), ('sales', 0), ('leads', 2)]), 
        bson.son.SON([('name', 'b'), ('sales', 5), ('leads', 1)]),
        bson.son.SON([('name', 'c'), ('sales', 3.3), ('leads', 1)])]})
client.test.foo.insert_one({
    'name': 'clientB',
    'locations': [
        bson.son.SON([('name', 'a'), ('sales', 6), ('leads', 1)]), 
        bson.son.SON([('name', 'b'), ('sales', 6), ('leads', 3)]),
        bson.son.SON([('name', 'c'), ('sales', 1.3), ('leads', 4)])]})

А теперь сортировка по имени:

client.test.foo.aggregate([{'$project': {'maxItem': {'$max': '$locations'}}}]))

Возвращает:

[{'_id': ObjectId('5b99619beabb0f0d86dcedaf'),
  'maxItem': {'leads': 1, 'name': 'c', 'sales': 3.3}},
 {'_id': ObjectId('5b99619beabb0f0d86dcedb0'),
  'maxItem': {'leads': 4, 'name': 'c', 'sales': 1.3}}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...