$ max如何在一系列对象上工作?

时间:2018-09-12 18:52:10

标签: mongodb aggregation-framework

使用这些文档作为示例集合:

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 :(得分:0)

我发现了这个 https://docs.mongodb.com/manual/reference/bson-type-comparison-order/#objects 哪个状态:

MongoDB对BSON对象的比较使用以下顺序:

  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}}]