簡體   English   中英

如何在mongoDB中存儲多維數組

[英]how to store multi-dimensional array in mongoDB

在這里問了一個問題。簡單來說,我的算法需要一個四維數組。 大小可以達到32G。 所以我打算將其存儲在MongoDB中。 我已經按照自己的方式實施了。 由於我以前從未使用過MongoDB,因此我的實現太慢了,那么如何將這四個維度的數組存儲在MongoDB中呢?

一些統計:

由於整個陣列的大小約為12 * 7000 * 100 * 500,並且我的服務器是Windows Server 2008 R2 Standard,具有16.0GB的內存,因此更新整個陣列將需要幾個小時的時間(我猜是十多個,因為我沒有等待)。 cpu是Intel®Xeon®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”},“ key”:“ 1_2_3_4”,“ value”:113.1232}

{“ _id”:{“ $ oid”:“ 51e0c6f15a66ea5c32a99774”},“ key”:“ 1_2_3_5”,“ value”: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);
    }
}

很少的建議

  • 由於您的數據庫大小超出了(實際上是2倍)RAM的大小。 也許你應該看看拆分 當您可以在內存中容納數據庫大小時,Mongo會很好地工作。

  • 將字段存儲為字符串不僅消耗更多的內存,而且字符串比較的速度也較慢。 我們可以輕松地將此字段存儲在NumberLong (MongoDB的Long數據類型)中。 由於您已經知道陣列的最大大小為12 * 7000 * 100 * 500

    我假設任何尺寸的最大尺寸不能超過10,000。 因此,您集合中的元素總數少於(10000 ** 4)。

    因此,如果您希望元素位於p_z_d_wt_wv 1 [2] [3] [4],則將索引計算為

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

    您從右到左移動,增加基數的功效,然后將其乘以該位置上的任何值,最后取它們的總和。

    將此字段編入索引,我們應該期望有更好的性能。

由於您只有一個龐大的數組,因此建議您使用內存映射文件。 這將使用大約32 GB的磁盤空間,並且效率更高。 即使這樣,隨機訪問比主內存大的數據集總是很慢,除非SDD快(購買更多的內存會更便宜)

如果Mongo DB對您而言足夠快地執行,我將感到非常驚訝。 如果更新需要十小時,那么一次掃描也可能需要十小時。 如果您有SSD,則內存映射文件可能需要大約三分鍾的時間。 如果數據全部在內存中,例如您有48 GB(您將需要32 GB以上的可用空間而不是總計),那么這將減少到幾秒鍾。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM