Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在mongoDB中存储多维数组_Java_Mongodb_Mongodb Java - Fatal编程技术网

Java 如何在mongoDB中存储多维数组

Java 如何在mongoDB中存储多维数组,java,mongodb,mongodb-java,Java,Mongodb,Mongodb Java,我问了一个问题。简单地说,我的算法需要一个四维数组。尺寸可达32G。所以我计划将其存储在MongoDB中。我已经用我的方式实现了它。因为我以前从未使用过MongoDB,所以我的实现太慢了,所以我应该如何在MongoDB中存储这个四维数组呢 一些统计数据: 由于我的阵列大小约为12*7000*100*500,而且我的服务器是Windows server 2008 R2标准,内存为16.0GB,cpu是Intel(R)Xeon(R)cpu,2.67GHz,因此需要几个小时(我想可能需要十多个小时)才

我问了一个问题。简单地说,我的算法需要一个四维数组。尺寸可达32G。所以我计划将其存储在MongoDB中。我已经用我的方式实现了它。因为我以前从未使用过MongoDB,所以我的实现太慢了,所以我应该如何在MongoDB中存储这个四维数组呢

一些统计数据:

由于我的阵列大小约为12*7000*100*500,而且我的服务器是Windows server 2008 R2标准,内存为16.0GB,cpu是Intel(R)Xeon(R)cpu,2.67GHz,因此需要几个小时(我想可能需要十多个小时)才能更新整个阵列。我的mongoDB版本是2.4.5

稍微解释一下我的实现。 我的数组有四个维度,分别命名为z、d、wt和wv

首先,我为数组元素构造一个字符串。以数组元素p_z_d_wt_wv[1][2][3][4]为例,因为z是1,d是2,wt是3,wv是4,我得到一个字符串“1_2_3_4”,它代表p_z_d_wt_wv[1][2][3][4]。然后我将p_z_d_wt wv[1][2][3][4]的值存储在数据库中。 因此,我的数据如下所示:

{“_id”:{“$oid”:“51e0c6f15a66ea5c32a99773”},键:“1_2_3_4”,“值”:113.1232}

{“_id”:{“$oid”:“51e0c6f15a66ea5c32a99774”},键:“1_2_3_5”,“值”:11.1243}

任何建议都将不胜感激

提前谢谢

下面是我的代码

public class MongoTest {

    private Mongo mongo = null;
    private DB mmplsa;
    private DBCollection p_z_d_wt_wv;
    private DBCollection p_z_d_wt_wv_test;
    public void init()
    {
        try{
        mongo = new Mongo();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (MongoException e) {
            e.printStackTrace();
        }

        mmplsa = mongo.getDB("mmplsa");
        p_z_d_wt_wv = mmplsa.getCollection("p_z_d_wt_wv");    
    }

    public void createIndex()
    {
        BasicDBObject query = new BasicDBObject("key",1);
            p_z_d_wt_wv.ensureIndex(query,null, true);
    }

    public void add( String key, double value)
    {
        DBObject element = new BasicDBObject();
        element.put("key", key);
            element.put("value", value);
        p_z_d_wt_wv.insert(element);
    }

    public Double query(String key)
    {

        BasicDBObject specific_key = new BasicDBObject("value",1).append("_id", false);
        DBObject obj = p_z_d_wt_wv.findOne(new    BasicDBObject("key",key),specific_key );    
            return (Double)obj.get("value");
    }

    public void update(boolean ifTrainset, String key, double new_value)
    {
        BasicDBObject query = new BasicDBObject().append("key", key);
        BasicDBObject updated_element = new BasicDBObject();
        updated_element.append("$set", new BasicDBObject().append("value", new_value));
        p_z_d_wt_wv.update(query, updated_element);
    }
}
几点建议

  • 因为您的数据库大小超过了RAM的大小(实际上是2倍)。也许你应该看看。当您可以在内存中调整数据库大小时,Mongo工作得很好

  • 将字段存储为字符串不仅会消耗更多内存,而且字符串比较速度较慢。我们可以轻松地将此字段存储在
    NumberLong
    (MongoDB的Long数据类型)中。因为您已经知道阵列的最大大小是12*7000*100*500

    我假设任何维度的最大大小不能超过10000。因此,集合中的元素总数少于(10000**4)

    所以如果你想要元素在p_z_d_wt_wv[2][3][4] 您可以将索引计算为

    (10000**0*4)+(10000**1*3)+(10000**2*3)+(10000*3*1

    你从右到左,增加你的基数,乘以这个位置上的任何值,最后取它们的和

    为该字段编制索引,我们应该期望更好的性能


由于您只有一个大数组,我建议您使用内存映射文件。这将使用大约32GB的磁盘空间,而且效率更高。即便如此,随机访问比主内存大的数据集的速度总是很慢,除非您有一个快速SDD(购买更多内存会更便宜)

如果Mongo DB对您的表现足够快,我会非常惊讶。如果更新需要十个小时,那么扫描一次也可能需要十个小时。如果您有SSD,则内存映射文件可能需要大约三分钟的时间。如果数据都在内存中,例如,您有48 GB(您需要32+GB的空闲空间,而不是总空间),则这将下降到秒


您无法克服硬件的限制。;)

你也可以给我们一些关于它有多慢的统计数据,机器规格,mongo版本。我已经在我的帖子中添加了这些统计数据。谢谢你的提醒,谢谢你的帮助。Java中的内存映射文件是否有大小限制,因为阵列的大小可以达到32G硬盘用于在重负载下保持高数据库性能,即使系统具有可扩展性。通常数据大小超过RAM大小(也是数百倍),但在所有这些情况下不需要分片。在某些情况下,即使数据大小适合RAM大小,也可能需要分片。为了保持性能,您必须确保索引大小适合RAM大小。