如何从 MongoDB 数组中检索第一个和最后一个元素并将其设置为不同的字段?

How to retrieve first and last elements from MongoDB array and set it as distinct fields?

我的collection:

{
        "_id" : ObjectId("60e46c1dfc320656ffc683b4"),
        "name" : "A",
        "name_test" : "a b c",
        "arr" : [
                "1",
                "2",
                "3"
        ]
}
{
        "_id" : ObjectId("60e46c20fc320656ffc683b5"),
        "name" : "B",
        "name_test" : "B A",
        "arr" : [
                "a",
                "b",
                "c"
        ]
}
{
        "_id" : ObjectId("60e46c26fc320656ffc683b6"),
        "name" : "T1",
        "number" : 1,
        "name_test" : "T1",
        "arr" : [
                "t1",
                "t2",
                "t3"
        ]
}

我想用数组“arr”的 firstlast 元素扩展字段,例如:

{
            "_id" : ObjectId("60e46c26fc320656ffc683b6"),
            "name" : "T1",
            "number" : 1,
            "name_test" : "T1",
            "arr" : [
                    "t1",
                    "t2",
                    "t3"
            ],
            "first": "t1",
            "last": "t3"
    }

我正在为 Mongo 尝试此命令:

db.test_coll.update({}, 
        [{ $set: 
              { first: { $arrayElemAt: [ "$arr", 0 ]}, 
                last: { $arrayElemAt: [ "$arr", -1 ]} }
              },
        ])
                        

我也试过:

db.test_dups.updateMany({$where: "this.arr.length > 1"}, ...

但是没有成功。我遇到下一个错误:

[thread1] Error: the update operation document must contain atomic operators :
DBCollection.prototype.updateMany@src/mongo/shell/crud_api.js:568:1

我该怎么做?也许使用 PyMongo?


问题解决: 我的 mongo 是 3.2,大多数命令在那里不起作用,所以我使用 PyMongo:

解决了它
bulk = db.test.initialize_ordered_bulk_op()

cnt = 0
for profiles in db.test.find():
    cnt += 1 
    
    try:
        bulk.find({'_id': profiles['_id']}).update({'$set': {
                'f': profiles['arr'][0],
                'l': profiles['arr'][-1]
            }
        })

        if cnt % 1000000 == 0:
            print("Exectuting", cnt)
            bulk.execute()
            bulk = db.test.initialize_ordered_bulk_op()
    except:
        print(profiles['_id'], " - Did not worked out")
    
try:
    bulk.execute()
except:
    print("Bulk is Empty")
  • $expr$gt 检查 arr 长度应大于 1
  • $first$last 运算符到 arr
  • 中的 select 个元素
db.test_dups.updateMany(
  { $expr: { $gt: ["$arr", 1] } },
  [{
    $set: {
      first: { $first: "$arr" },
      last: { $last: "$arr" }
    }
  }]
)

Playground


问题解决: 我的 mongo 是 3.2,大多数命令在那里不起作用,所以我使用 PyMongo 解决了它:

bulk = db.test.initialize_ordered_bulk_op()

cnt = 0
for profiles in db.test.find():
    cnt += 1 
    
    try:
        bulk.find({'_id': profiles['_id']}).update({'$set': {
                'f': profiles['arr'][0],
                'l': profiles['arr'][-1]
            }
        })

        if cnt % 1000000 == 0:
            print("Exectuting", cnt)
            bulk.execute()
            bulk = db.test.initialize_ordered_bulk_op()
    except:
        print(profiles['_id'], " - Did not worked out")
    
try:
    bulk.execute()
except:
    print("Bulk is Empty")