2012-01-08 54 views
4

我是新來的MongoDB,我想把我的頭周圍是否能方便使用MongoDB的不俗的性能執行此查詢操作。我想通過數字和數組參數的查詢,並使用它們通過元件操作上數組值集合中的每個文件在執行元件。這可能嗎?的MongoDB - 查詢與反序列參數元素

例如集合包含諸如下列文件:

{ 
    "name" : "item1", 
    "m" : 5.2, 
    "v" : 1.1, 
    "data1" : [ 0, 0, 0.3, 0.7, 0.95, 0.9, 0.75, 0.4, 0.1, 0 ], 
    "data2" : [ 0, -1, 0, 1, 1, 0 ] 
} 

我遇到的問題可能是這個樣子的另一個「搜索」文件:

{ 
    "x" : 8, 
    "K" : 1, 
    "dataA" : [ 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 0.5], 
    "dataB" : [ 0, -2, 0, 1, 1, 0 ] 
} 

我想運行一個查詢,或映射簡化,使用針對上面的收集上述搜索文檔返回一個包含集合:

{ 
    "name", 
    "y" = fn(m, v, x, K) = Kvx^(1/m) (not the real formula but just an example) 
    "dataF" = Max(i=0..9) {data1[i] * dataA[i] } 
    "dataS" = Sum(j=0..5) {data2[j] * dataB[j] } 
} 
where y>0 

因此,對於上面的例子中,返回結果將是

{ 
    "name" : "item1", 
    "y" : 1 * 1.1 * 8^5.2 = 1.641 
    "dataF" : Max(..., 0.4*0.5, 0.1*1, 0 * 0.5) = 0.2 
    "dataS" : 0*0 + (-1)*(-2) + 0*0 + 1*1 + 1*1 + 0*0 = 4 
} 

這是要使用MongoDB可能/方便嗎?

注:在我的應用程序會出現使用標準MongoDB的操作,所以我希望能在查詢上述處理,避免做客戶端包含在搜索更加規範標準。

回答

2

這裏有一個的map/reduce版本:

db.data.save({ 
    "name" : "item1", 
    "m" : 5.2, 
    "v" : 1.1, 
    "data1" : [ 0, 0, 0.3, 0.7, 0.95, 0.9, 0.75, 0.4, 0.1, 0 ], 
    "data2" : [ 0, -1, 0, 1, 1, 0 ] 
}); 

db.data.mapReduce(function() { 
    var searchdoc = { 
    "x" : 8, 
    "K" : 1, 
    "dataA" : [ 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 0.5], 
    "dataB" : [ 0, -2, 0, 1, 1, 0 ] 
    }; 

    var result = {name: this.name}; 
    result.y = searchdoc.K * this.v * Math.pow(searchdoc.x, 1/this.m); 
    if(result.y > 0) { 
    result.dataF = 0; 
    for(i=0;i<this.data1.length;i++) { 
     var f = this.data1[i] * searchdoc.dataA[i]; 
     if(f > result.dataF) { 
     result.dataF = f; 
     } 
    } 
    result.dataS = 0; 
    for(i=0;i<this.data2.length;i++) { 
     var s = this.data2[i] * searchdoc.dataB[i]; 
     result.dataS += s; 
    } 
    emit(this.name, result); 
    } 
}, function(key, values){}, {out: {inline: 1}}); 

結果:

{ 
"results" : [ 
    { 
     "_id" : "item1", 
     "value" : { 
      "name" : "item1", 
      "y" : 1.640830939540542, 
      "dataF" : 0.2, 
      "dataS" : 4 
     } 
    } 
], 
"timeMillis" : 0, 
"counts" : { 
    "input" : 1, 
    "emit" : 1, 
    "reduce" : 0, 
    "output" : 1 
}, 
"ok" : 1, 
} 

這是外殼的版本:

db.data.save({ 
    "name" : "item1", 
    "m" : 5.2, 
    "v" : 1.1, 
    "data1" : [ 0, 0, 0.3, 0.7, 0.95, 0.9, 0.75, 0.4, 0.1, 0 ], 
    "data2" : [ 0, -1, 0, 1, 1, 0 ] 
}); 

var searchdoc = { 
    "x" : 8, 
    "K" : 1, 
    "dataA" : [ 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 0.5], 
    "dataB" : [ 0, -2, 0, 1, 1, 0 ] 
}; 

var search = function(searchdoc) { 
    db.data.find().forEach(function(obj) { 
    var result = {name:obj.name}; 
    result.y = searchdoc.K * obj.v * Math.pow(searchdoc.x, 1/obj.m); 
    if(result.y > 0) { 
     result.dataF = 0; 
     for(i=0;i<obj.data1.length;i++) { 
     var f = obj.data1[i] * searchdoc.dataA[i]; 
     if(f > result.dataF) { 
      result.dataF = f; 
     } 
     } 
     result.dataS = 0; 
     for(i=0;i<obj.data2.length;i++) { 
     var s = obj.data2[i] * searchdoc.dataB[i]; 
     result.dataS += s; 
     } 
     db.results.save(result); 
    } 
    }); 
} 

search(searchdoc); 

db.results.find(); 
{ "_id" : ObjectId("4f08ffe4264d23670eeaaadf"), "name" : "item1", "y" : 1.640830939540542, "dataF" : 0.2, "dataS" : 4 } 
+0

更新,增加的map/reduce版本。 – 2012-01-08 03:35:10

+1

的快速反應感謝@wes,很有意思,你提出的解決方案是非常有幫助,我將加載一些數據,並嘗試兩種方法來嘗試獲得比較性能的感覺,將發佈一些成果。乾杯 – 2012-01-08 11:52:19