首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有一种方法可以用MongoDB驱动程序填充大容量插入向量,然后在不进行克隆的情况下再次使用它?

是否有一种方法可以用MongoDB驱动程序填充大容量插入向量,然后在不进行克隆的情况下再次使用它?
EN

Stack Overflow用户
提问于 2018-06-21 13:44:05
回答 2查看 969关注 0票数 1

我想使用MongoDB锈蚀驱动器将文档批量插入到集合中。我有一个bulk向量,当我达到给定的大小时,它会被填充和冲洗。

我的问题是,当将向量提供给驱动程序的API .clone() bulk_write()时,必须对其进行API处理。

如果我不克隆,我有一个E0382:在移动错误之后使用,而且似乎API不接受引用(E0308: expected struct found )。

我对锈病很陌生。有没有办法做到这一点而不克隆这个大结构呢?(结构在我的示例中不是很大,但在我的实际代码中)

这是我的密码:

代码语言:javascript
复制
// Cargo.toml extract:
//
// [dependencies]
// bson = "0.10"
// mongodb = "0.3.7"

#[macro_use(bson, doc)] extern crate bson;
extern crate mongodb;
use mongodb::coll::options::WriteModel;
use mongodb::{Client, ThreadedClient};
use mongodb::db::ThreadedDatabase;

fn main() {

    // Connect to MongoDB and select collection
    let client = Client::connect("localhost", 27017).ok().expect("Failed to initialize client.");
    let coll = client.db("test").collection("mycol");

    // Make the bulk vector
    let mut bulk = Vec::new();
    for i in 0..1000 {

        // Append a item to the bulk
        bulk.push(WriteModel::UpdateOne { filter: doc!{"_id": i},
                                          update: doc!{"$set" => {"hello" => "world"}},
                                          upsert: Some(true) });

        // Each 11 items, flush bulk
        if bulk.len() > 10 {
            println!("Upsert {} docs into collection...",bulk.len());

            // `bulk` have to be cloned here
            let result = coll.bulk_write(bulk.clone(), true); // Unoptimal: bulk cloned
            //let result = coll.bulk_write(bulk, true); // E0382: use after move
            //let result = coll.bulk_write(&bulk, true); // E0308: expected struct `std::vec::Vec`, found reference 

            // Check result
            match result.bulk_write_exception {
                Some(exception) => {
                    if exception.message.len()>0 {
                        println!("ERROR: {}",exception.message);
                    }
                }
                None => ()
            }
            bulk.clear();
        }
    }

    // Final flush
    if bulk.len() > 0 {
        println!("Upsert {} docs into collection...",bulk.len());
        let result = coll.bulk_write(bulk.clone(), true);
        match result.bulk_write_exception {
            Some(exception) => {
                if exception.message.len()>0 {
                    println!("ERROR: {}",exception.message);
                }
            }
            None => ()
        }
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-06-21 15:10:50

正如@kazemakase在评论中指出的那样,这类问题的一般解mem::replace()。但是,在这种情况下,我们需要保留bulk的原因是在bulk.len() <= 10的最后一种情况下。如果重构原始代码,则可以完全避免在移动错误后使用:

代码语言:javascript
复制
// Connect to MongoDB and select collection
let client = Client::connect("localhost", 27017).ok().expect("Failed to initialize client.");
let coll = client.db("test").collection("mycol");

let ranges: Vec<_> = (0..1000).into_iter().collect();
for range in ranges[..].chunks(11) {
    let bulk: Vec<_> = 
        range.map(|i| WriteModel::UpdateOne { filter: doc!{"_id": i},
                                              update: doc!{"$set" => {"hello" => "world"}},
                                              upsert: Some(true) })
        .collect();

    println!("Upsert {} docs into collection...", bulk.len());

    let result = coll.bulk_write(bulk);
    if let Some(exception) = result.bulk_write_exception {
        if exception.message.len() > 0 {
            println!("ERROR: {}", exception.message);
        }
    }
}

这里的主要更改是使用slice::chunks(),而不是在主迭代循环中手动将块构建到bulk中。另一件好的事情是,这消除了重复的错误处理,是更惯用的锈蚀。

票数 2
EN

Stack Overflow用户

发布于 2018-06-21 14:44:34

感谢kazemakase,我可以通过创建一个新的空向量来解决我自己的问题,交换两个向量并发送完整的向量。以下是新的工作代码:

代码语言:javascript
复制
// Cargo.toml extract:
//
// [dependencies]
// bson = "0.10"
// mongodb = "0.3.7"

#[macro_use(bson, doc)] extern crate bson;
extern crate mongodb;
use mongodb::coll::options::WriteModel;
use mongodb::{Client, ThreadedClient};
use mongodb::db::ThreadedDatabase;
use std::mem;

fn main() {

    // Connect to MongoDB and select collection
    let client = Client::connect("localhost", 27017).ok().expect("Failed to initialize client.");
    let coll = client.db("test").collection("mycol");

    // Make the bulk vector
    let mut bulk = Vec::new();
    for i in 0..1000 {

        // Append a item to the bulk
        bulk.push(WriteModel::UpdateOne { filter: doc!{"_id": i},
                                          update: doc!{"$set" => {"hello" => "world"}},
                                          upsert: Some(true) });

        // Each 11 items, flush bulk
        if bulk.len() > 10 {
            println!("Upsert {} docs into collection...",bulk.len());

            let mut bulk2 = Vec::new(); // create new empty bulk
            mem::swap(&mut bulk, &mut bulk2); // bulk <-> bulk2
            let result = coll.bulk_write(bulk2, true);  // send full bulk

            //let result = coll.bulk_write(bulk.clone(), true); // Unoptimal: bulk cloned
            //let result = coll.bulk_write(bulk, true); // E0382: use after move
            //let result = coll.bulk_write(&bulk, true); // E0308: expected struct `std::vec::Vec`, found reference 

            // Check result
            match result.bulk_write_exception {
                Some(exception) => {
                    if exception.message.len()>0 {
                        println!("ERROR: {}",exception.message);
                    }
                }
                None => ()
            }
            //bulk.clear(); // bulk is now a new empty bulk, clear is unecessary
        } // Compiler will drop bulk2 (the full bulk) at this point
    }

    // Final flush
    if bulk.len() > 0 {
        println!("Upsert {} docs into collection...",bulk.len());
        let result = coll.bulk_write(bulk, true); // No clone nor swap needed here
        match result.bulk_write_exception {
            Some(exception) => {
                if exception.message.len()>0 {
                    println!("ERROR: {}",exception.message);
                }
            }
            None => ()
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50970102

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档