Saya ingin tahu apakah lebih cepat (mengimpor) menggunakan updateone atau updatemany dengan penulisan massal. Kode saya untuk mengimpor data ke dalam koleksi dengan tampilan pymongo adalah ini:

for file in sorted_files:
    df = process_file(file)
    for row, item in df.iterrows():
        data_dict = item.to_dict()
        bulk_request.append(UpdateOne(
            {"nsamples": {"$lt": 12}},
            {
                "$push": {"samples": data_dict},
                "$inc": {"nsamples": 1}
            },
            upsert=True
        ))
    result = mycol1.bulk_write(bulk_request)

Ketika saya mencoba memperbarui banyak, satu-satunya hal yang saya ubah adalah ini:

...
...
bulk_request.append(UpdateMany(..
..
..

Saya tidak melihat perbedaan besar dalam waktu penyisipan. Seharusnya tidak memperbarui Banyak cara yang lebih cepat? Mungkin saya melakukan sesuatu yang salah. Saran apa pun akan sangat membantu! Terima kasih sebelumnya!

Catatan:Data saya terdiri dari 1,2m baris. Saya ingin setiap dokumen berisi 12 subdokumen.

2
xaroulis gekas 11 Mei 2021, 11:37

2 jawaban

Jawaban Terbaik

Jawaban @Wernfried Domscheit benar.

Jawaban ini khusus untuk skenario Anda.

Jika Anda tidak keberatan untuk tidak memperbarui catatan ke dokumen yang ada dan memasukkan dokumen baru sekaligus, gunakan kode di bawah ini yang paling dioptimalkan untuk kasus penggunaan Anda.

sorted_files = []
process_file = None
for file in sorted_files:
    df = process_file(file)
    sample_data = []
    for row, item in df.iterrows():
        sample_data.append(item.to_dict())
        if len(sample_data) == 12:
            mycol1.insertOne({
                "samples": sample_data,
                "nsamples": len(sample_data),
            })
            sample_data = []
    mycol1.insertOne({
        "samples": sample_data,
        "nsamples": len(sample_data),
    })

Jika Anda ingin mengisi record yang ada dengan 12 objek dan kemudian membuat record baru, gunakan logika kode di bawah ini.

Catatan: Saya belum menguji kode di lokal saya, ini hanya untuk memahami aliran untuk Anda gunakan.

for file in sorted_files:
    df = process_file(file)
    sample_data = []
    continuity_flag = False
    for row, item in df.iterrows():
        sample_data.append(item.to_dict())
        if not continuity_flag:
            sample_rec = mycol1.find_one({"nsamples": {"$lt": 12}}, {"nsamples": 1})
            if sample_rec is None:
                continuity_flag = True
            elif sample_rec["nsamples"] + len(sample_data) == 12:
                mycol1.update_one({
                    "_id": sample_rec["_id"]
                }, {
                    "$push": {"samples": {"$each": sample_data}},
                    "$inc": {"nsamples": len(sample_data)}
                })
        if len(sample_data) == 12:
            mycol1.insert_one({
                "samples": sample_data,
                "nsamples": len(sample_data),
            })
            sample_data = []
    if sample_data:
        mycol1.insert_one({
            "samples": sample_data,
            "nsamples": len(sample_data),
        })
1
hhharsha36 12 Mei 2021, 04:55

updateOne hanya memperbarui dokumen pencocokan pertama untuk nsamples: {$lt: 12}. Jadi updateOne harus lebih cepat.

Namun, mengapa Anda memasukkannya satu per satu? Letakkan semua dalam satu dokumen dan buat satu pembaruan. Mirip dengan yang ini:

sample_data = [];
for row, item in df.iterrows():
    data_dict = item.to_dict();
    sample_data.append(data_dict);
db.mycol1.updateOne(
  {"nsamples": {"$lt": 12}},
  { 
     "$push": { samples: { $each: sample_data } },
     "$inc": {"nsamples": len(sample_data) }
  }
)
1
Wernfried Domscheit 11 Mei 2021, 09:45