Вычисление частотомера всех уникальных значений вложенного поля

В javascript мы можем получить доступ с помощью:

  • точечной нотации - foo.bar
  • квадратных скобок - foo[someVar] или foo["string"]

Но только второй случай позволяет динамически обращаться к свойствам:

var foo = { pName1 : 1, pName2 : [1, {foo : bar }, 3] , ...}

var name = "pName"
var num  = 1;

foo[name + num]; // 1

// -- 

var a = 2;
var b = 1;
var c = "foo";

foo[name + a][b][c]; // bar
1
задан Neil Lunn 24 March 2019 в 09:05
поделиться

1 ответ

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

cursor = db.sample.aggregate([
  { "$group": {
    "_id": "$b.d",
    "count": { "$sum": 1 }
  }},
  { "$group": {
     "_id": None,
     "data": { "$push": { "k": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

{ 'x': 1, 'xx': 2, 'xxx': 1 }

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

cursor = db.sample.aggregate([
  { "$group": {
    "_id": "$b.d",
    "count": { "$sum": 1 }
  }}
])

data = list(cursor)

result = reduce(
  lambda x,y:
    dict(x.items() + { y['_id']: y['count'] }.items()), data,{})

print(result)

, который возвращает точно то же самое:

{ 'x': 1, 'xx': 2, 'xxx': 1 }

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

{ "_id" : "xxx", "count" : 1 }
{ "_id" : "xx", "count" : 2 }
{ "_id" : "x", "count" : 1 }

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

db.sample.aggregate([
  { "$addFields": { "b": { "$objectToArray": "$b" } } },
  { "$unwind": "$b" },
  { "$group": {
    "_id": {
      "_id": "$b.k",
      "k": "$b.v"
    },
    "count": { "$sum": 1 }

  }},
  { "$group": {
    "_id": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

{ "_id" : "c", "data" : { "25" : 3, "5" : 1 } }
{ "_id" : "e", "data" : { "36" : 4 } }
{ "_id" : "d", "data" : { "xxx" : 1, "xx" : 2, "x" : 1 } }

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

cursor = db.sample.aggregate([
  { "$addFields": { "b": { "$objectToArray": "$b" } } },
  { "$unwind": "$b" },
  { "$group": {
    "_id": {
      "_id": "$b.k",
      "k": "$b.v"
    },
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id._id", "data": { "$push": { "k": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id.k", "v": "$count" } } }} ]) data = list(cursor) result = map(lambda d: { '_id': d['_id'], 'data': reduce(lambda x,y: dict(x.items() + { y['k']: y['v'] }.items()), d['data'], {}) },data)
id._id", "data": { "$push": { "k": { "$toString": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

{ "_id" : "c", "data" : { "25" : 3, "5" : 1 } }
{ "_id" : "e", "data" : { "36" : 4 } }
{ "_id" : "d", "data" : { "xxx" : 1, "xx" : 2, "x" : 1 } }

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

cursor = db.sample.aggregate([
  { "$addFields": { "b": { "$objectToArray": "$b" } } },
  { "$unwind": "$b" },
  { "$group": {
    "_id": {
      "_id": "$b.k",
      "k": "$b.v"
    },
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id._id", "data": { "$push": { "k": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id.k", "v": "$count" } } }} ]) data = list(cursor) result = map(lambda d: { '_id': d['_id'], 'data': reduce(lambda x,y: dict(x.items() + { y['k']: y['v'] }.items()), d['data'], {}) },data)
id.k" }, "v": "$count" } } }}, { "$addFields": { "data": { "$arrayToObject": "$data" } }} ])

Что будет возвращать:

{ "_id" : "c", "data" : { "25" : 3, "5" : 1 } }
{ "_id" : "e", "data" : { "36" : 4 } }
{ "_id" : "d", "data" : { "xxx" : 1, "xx" : 2, "x" : 1 } }

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

cursor = db.sample.aggregate([
  { "$addFields": { "b": { "$objectToArray": "$b" } } },
  { "$unwind": "$b" },
  { "$group": {
    "_id": {
      "_id": "$b.k",
      "k": "$b.v"
    },
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id._id", "data": { "$push": { "k": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id.k", "v": "$count" } } }} ]) data = list(cursor) result = map(lambda d: { '_id': d['_id'], 'data': reduce(lambda x,y: dict(x.items() + { y['k']: y['v'] }.items()), d['data'], {}) },data)
id", "v": "$count" } } }}, { "$replaceRoot": { "newRoot": { "$arrayToObject": "$data" } }} ]) for doc in cursor: print(doc)

Возвращает

{ 'x': 1, 'xx': 2, 'xxx': 1 }

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

cursor = db.sample.aggregate([
  { "$group": {
    "_id": "$b.d",
    "count": { "$sum": 1 }
  }}
])

data = list(cursor)

result = reduce(
  lambda x,y:
    dict(x.items() + { y['_id']: y['count'] }.items()), data,{})

print(result)

, который возвращает точно то же самое:

{ 'x': 1, 'xx': 2, 'xxx': 1 }

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

{ "_id" : "xxx", "count" : 1 }
{ "_id" : "xx", "count" : 2 }
{ "_id" : "x", "count" : 1 }

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

db.sample.aggregate([
  { "$addFields": { "b": { "$objectToArray": "$b" } } },
  { "$unwind": "$b" },
  { "$group": {
    "_id": {
      "_id": "$b.k",
      "k": "$b.v"
    },
    "count": { "$sum": 1 }

  }},
  { "$group": {
    "_id": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

{ "_id" : "c", "data" : { "25" : 3, "5" : 1 } }
{ "_id" : "e", "data" : { "36" : 4 } }
{ "_id" : "d", "data" : { "xxx" : 1, "xx" : 2, "x" : 1 } }

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

cursor = db.sample.aggregate([
  { "$addFields": { "b": { "$objectToArray": "$b" } } },
  { "$unwind": "$b" },
  { "$group": {
    "_id": {
      "_id": "$b.k",
      "k": "$b.v"
    },
    "count": { "$sum": 1 }
  }},
  { "$group": {
    "_id": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id._id", "data": { "$push": { "k": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно сделать, это запустить его, извлечь результаты и объединить их в один словарь в качестве желаемого результата:

[112]

, который возвращает точно то же самое:

[113]

Более того, он делает это без гимнастики , требуемой путем добавления других этапов агрегирования и операторов, и вы не изменили то, что действительно возвращается с сервера, так как первоначальный ответ $group в основном :

[114]

Таким образом, настоящий урок здесь заключается в том, что вы можете делать необычные манипуляции в конвейере агрегации, что вы действительно должны учитывать, так это то, что вы , вероятно, не должны когда альтернатива чище и гораздо более читаемый код.

Для справки, все, что происходит, это дополнительные $group используют $push для создания массива с ключами k и v, как и следовало ожидать в следующий этап трубопровода. Где этот следующий этап использует $replaceRoot для получения выходных данных $arrayToObject из этого массива, созданного на предыдущем этапе, и в основном преобразует его в объект / словарь.

Напротив, reduce делает то же самое. Мы в основном берем результаты курсора в list, чтобы функции python могли действовать в этом списке. Тогда это просто вопрос обхода элементов в этом списке, которые всегда имеют _id в качестве ключа, и другого именованного свойства для «подсчитанного» выхода (здесь мы использовали count) и простого преобразования их в качестве ключа [ 1143] и значения пары для окончательного вывода словаря.


Просто для забавы, кое-что, основанное на ваших первоначальных попытках, может быть:

[115]

Что будет возвращать:

[116]

Опять тот же результат без дополнительного этапы конвейера для преобразования происходят из использования map и reduce с python:

[117]id.k", "v": "$count" } } }} ]) data = list(cursor) result = map(lambda d: { '_id': d['_id'], 'data': reduce(lambda x,y: dict(x.items() + { y['k']: y['v'] }.items()), d['data'], {}) },data)
id._id", "data": { "$push": { "k": { "$toString": "

Вы в основном подходите к этому неправильно. У вас есть четкий путь к "b.d" в качестве ключа, по которому вы хотите агрегировать, нет необходимости преобразовывать его в массив:

[110]

Возвращает

[111]

Но это на самом деле излишне, так как в действительности вся работа была сделана в этом первоначальном $group утверждении. Все, что вам действительно нужно

0
ответ дан Neil Lunn 24 March 2019 в 09:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: