Java MongoDB-合并集合和映射-可以提高性能

Java MongoDB-合并集合和映射-可以提高性能,java,oracle,mongodb,plsql,merge,Java,Oracle,Mongodb,Plsql,Merge,下面的功能将word MongoDB集合与地图内容合并如下: 收藏: 第三类, 狗5 地图: 狗2, 斑马1 合并后的集合: 第三类, 狗7, 斑马1 我们有大约14000个元素的空集合和地图 Oracle PL/SQL过程使用一个在15k RPM硬盘上运行的合并SQL,在不到一秒钟的时间内完成 SSD磁盘上的MongoBD大约需要53秒 看起来Oracle在内存中准备了文件操作的映像 并在一次i/o操作中保存结果 MongoDB可能有14000个i/o—每个插入大约4毫秒。这与SSD的性能相对

下面的功能将word MongoDB集合与地图内容合并如下:

收藏: 第三类, 狗5

地图: 狗2, 斑马1

合并后的集合: 第三类, 狗7, 斑马1

我们有大约14000个元素的空集合和地图

Oracle PL/SQL过程使用一个在15k RPM硬盘上运行的合并SQL,在不到一秒钟的时间内完成

SSD磁盘上的MongoBD大约需要53秒

看起来Oracle在内存中准备了文件操作的映像 并在一次i/o操作中保存结果

MongoDB可能有14000个i/o—每个插入大约4毫秒。这与SSD的性能相对应

如果我只做了14000次插入,而没有搜索文档,就像在合并的情况下一样,那么一切工作也会很快——不到一秒钟

我的问题是:

  • 代码可以改进吗

  • 也许有必要对MongoDB配置做些什么

  • 功能代码:

    public void addBookInfo(String bookTitle, HashMap<String, Integer> bookInfo)
    {
        // insert information to the book collection
        Document d = new Document();
        d.append("book_title", bookTitle);
        book.insertOne(d);
        // insert information to the word collection
        // prepare collection of word info and book_word info documents
        List<Document> wordInfoToInsert = new ArrayList<Document>();
        List<Document> book_wordInfoToInsert = new ArrayList<Document>();
        for (String key : bookInfo.keySet())
        {
            Document d1 = new Document();
            Document d2 = new Document();
            d1.append("word", key);
            d1.append("count", bookInfo.get(key));
            wordInfoToInsert.add(d1);
            d2.append("book_title", bookTitle);
            d2.append("word", key);
            d2.append("count", bookInfo.get(key));
            book_wordInfoToInsert.add(d2);
        }
        // this is collection of insert/update DB operations
        List<WriteModel<Document>> updates = new ArrayList<WriteModel<Document>>();
        // iterator for collection of words
        ListIterator<Document> listIterator = wordInfoToInsert.listIterator();
        // generate list of insert/update operations
        while (listIterator.hasNext()) 
        {
            d = listIterator.next();
            String wordToUpdate = d.getString("word");
            int countToAdd = d.getInteger("count").intValue();
            updates.add(
                new UpdateOneModel<Document>(
                    new Document("word", wordToUpdate),
    
                    new Document("$inc",new Document("count", countToAdd)),
                    new UpdateOptions().upsert(true)
                )
            );
        }
        // perform bulk operation
        // this is slowly
        BulkWriteResult bulkWriteResult = word.bulkWrite(updates);
        boolean acknowledge = bulkWriteResult.wasAcknowledged();
        if (acknowledge)
            System.out.println("Write acknowledged.");
        else
            System.out.println("Write was not acknowledged.");
        boolean countInfo = bulkWriteResult.isModifiedCountAvailable();
        if (countInfo)
            System.out.println("Change counters avaiable.");
        else
            System.out.println("Change counters not avaiable.");
        int inserted = bulkWriteResult.getInsertedCount();
        int modified = bulkWriteResult.getModifiedCount();
        System.out.println("inserted: " + inserted);
        System.out.println("modified: " + modified);
        // insert information to the book_word collection
        // this is very fast
        book_word.insertMany(book_wordInfoToInsert);
    }   
    
    public void addBookInfo(字符串bookTitle,HashMap bookInfo)
    {
    //将信息插入到图书收藏中
    文件d=新文件();
    d、 附加(“书名”,书名);
    书籍.insertOne(d);
    //在word集合中插入信息
    //准备word信息和book_word信息文档的集合
    List wordInfoToInsert=new ArrayList();
    List book_wordInfoToInsert=new ArrayList();
    for(字符串键:bookInfo.keySet())
    {
    文件d1=新文件();
    文档d2=新文档();
    d1.附加(“单词”,键);
    d1.追加(“计数”,bookInfo.get(键));
    wordInfoToInsert.add(d1);
    d2.附加(“书名”,书名);
    d2.附加(“单词”,键);
    d2.追加(“计数”,bookInfo.get(键));
    新增(d2);
    }
    //这是插入/更新数据库操作的集合
    列表更新=新建ArrayList();
    //词集合迭代器
    ListIterator ListIterator=wordInfoToInsert.ListIterator();
    //生成插入/更新操作的列表
    while(listIterator.hasNext())
    {
    d=listIterator.next();
    String wordToUpdate=d.getString(“word”);
    int countToAdd=d.getInteger(“count”).intValue();
    更新。添加(
    新的UpdateModel(
    新文件(“word”,wordToUpdate),
    新文件(“$inc”,新文件(“计数”,计数添加)),
    new UpdateOptions().upsert(true)
    )
    );
    }
    //执行批量操作
    //这是缓慢的
    BulkWriteResult BulkWriteResult=word.bulkWrite(更新);
    boolean acknowledge=bulkWriteResult.wasAcknowledged();
    如果(确认)
    System.out.println(“写入已确认”);
    其他的
    System.out.println(“未确认写入”);
    boolean countInfo=bulkWriteResult.isModifiedCountAvailable();
    if(countInfo)
    System.out.println(“可用的更改计数器”);
    其他的
    System.out.println(“更改计数器不可用”);
    int inserted=bulkWriteResult.getInsertedCount();
    int modified=bulkWriteResult.getModifiedCount();
    System.out.println(“插入:”+插入);
    System.out.println(“修改:”+修改);
    //将信息插入到书籍\u word集合中
    //这很快
    book\u word.insertMany(book\u wordInfoToInsert);
    }   
    
    有件事我不明白:你在“空集合”上执行upsert操作吗?此外,请提供示例文档–我真的不想从代码中重建它们的外观。谢谢您的重播。当然,集合可以是空的,也可以不是空的。但在这两种情况下,执行时间(53秒)没有太大差异:1)空集合,映射中有14000个单词,在它之后-重复操作-集合中有14000个单词,映射中有14000个单词-结果只是集合中单词的计数器加倍。集合的内容如下所示:>db.word.find(){“_id”:ObjectId(“56cf..”,“word”:“frowing”,“count”:56}我的问题是,是否可以使用其他Mongo API函数或更改一些MongoDB配置来加速操作。