2011-06-12 111 views
9

我有一個MongoDB集合~4M元素。從大的MongoDB集合中選擇每個第N個元素w/PHP?

我想抓住那些元素,通過整個集合間隔均勻的X號。

例如,您可以通過收集1000個元素 - 一個每4000行。

現在,我得到了整個集合中的光標,然後只寫每一個第N個元素。這給了我需要的東西,但巨大收藏的原始負載需要很長時間。

有沒有簡單的方法來做到這一點?現在我的猜測方法是對遞增的索引屬性進行JS查詢,並使用模數。一個PHP實現這一點:

db.collection.find({i:{$mod:[10000,0]}})

但這似乎可能將需要同樣多的時間查詢運行。

+0

做你找到任何解決辦法? – 2014-11-27 14:00:23

回答

0

我認爲主要的問題,是集可以在服務器上分佈,因此你必須遍歷整個集合。

+0

在這種情況下,我正在本地服務器上運行整個事情。 – blprnt 2011-06-14 17:16:09

0

不要將整個數據集放在遊標中。由於行順序並不重要,只是收集X隨機行了你的總的,返回的結果,然後修改這些記錄

+0

問題是我需要從我的集合中均勻分佈元素 - 即每第1000個元素。 – blprnt 2011-06-14 20:40:34

+0

創建一個計數字段,然後使用Map來過濾每個第n個元素,然後使用Reduce在該記錄上進行操作 – 2011-06-14 20:46:06

+0

謝謝......請嘗試一下。我已經有了一個計數字段。只需要嘗試使地圖的正面/反面減少文檔。 – blprnt 2011-06-14 21:05:58

0

我個人在「模數」值設計,用的東西,是一個函數來填充它數據的代表 - 所以如果您的數據每隔一段時間插入一次,您可以做一個模數的時間,如果沒有什麼可預測的話,那麼您可以使用隨機值;與這個大小的集合,它會趨向於平均分配很快。

使用隨機值的例子...

// add the index 
    db.example.ensureIndex({modulus: 1}); 
    // insert a load of data 
    db.example.insert({ your: 'data', modulus: Math.round((Math.random() * 1000) % 1000) }); 
    // Get a 1/1000 of the set 
    db.example.find({modulus: 1}); 
    // Get 1/3 of the set 
    db.example.find({modulus: { $gt: 0, $lt: 333 }}); 
-4

如果只有你的數據是在一個SQL數據庫,因爲它應該是......這個問題不會在PHP和答案將如此方便快捷......

加載到任何一個光標,而不是直接在數據庫中計算的信息絕對是一個壞主意,是不是可以直接在MongoDB中做到這一點啄?

+0

這個答案是如此落後 – jtromans 2014-02-06 16:20:40

+0

當只處理4M元素和做非MongoDB本地操作時,你應該使用PostgreSQL。 – 2014-03-01 18:41:01

+0

爲什麼?爲什麼PostgreSQL會在這裏變得更好?我是SQL數據庫的重要用戶,但對於大多數數據庫來說,這種查詢是不好的。另外,「MongoDB thingy」?看起來你並沒有真正知道你在MongoDB中談論的權威性。甚至不確定你的答案的第二部分是什麼意思。 – Sammaye 2014-06-18 08:05:35

0

這對於Map Reduce Job來說不是一個完美的用例嗎?

+0

道歉厚厚,但一些元代碼/實際代碼指示如何做到這一點將不勝感激。謝謝。 – 2014-08-17 14:59:08

+2

-1沒有回答這個問題,這應該是一個評論 – y3sh 2014-11-14 21:52:19

0

一個簡單的(低效的)方法就是使用流。

var stream = collection.find({}).stream(); 
var counter = 0; 

stream.on("data", function (document) { 
    counter++; 

    if (counter % 10000 == 0) { 
    console.log(JSON.stringify(document, null, 2)); 
    //do something every 10,000th time 
    } 
});