MongoDB Query查找集合的所有数组元素

时间:2013-03-21 10:13:04

标签: php mongodb mongodb-php nosql

我有一个非常大的MongoDB文档,它包含各种数据。我需要在集合中识别类型为array的字段,这样我就可以从我将填充的网格中显示的字段中删除它们。

我的方法现在包括使用

检索集合中的所有字段名称

这取自此处发布的回复MongoDB Get names of all keys in collection

mr = db.runCommand({
  "mapreduce" : "Product",
  "map" : function() {
    for (var key in this) { emit(key, null); }
  },
  "reduce" : function(key, stuff) { return null; }, 
  "out": "things" + "_keys"
})

db[mr.result].distinct("_id")

为每个字段运行一个像这样的查询

db.Product.find( { $where : "Array.isArray(this.Orders)" } ).count()

如果检索到任何内容,则该字段被视为数组。

我不喜欢我需要运行n + 2个查询(n是我的集合中不同字段的数量),我不想硬编码模型中的字段。它会破坏使用MongoDB的全部目的。

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我对您在上面提供的代码做了一些修改:

mr = db.runCommand({
  "mapreduce" : "Product",
  "map" : function() {
    for (var key in this) { 
       if (Array.isArray(this[key])) {
          emit(key, 1); 
       } else {
          emit(key, 0);
       }
    }
  },
  "reduce" : function(key, stuff) { return Array.sum(stuff); }, 
  "out": "Product" + "_keys"
})

现在,映射器将为包含数组的键发出1,为任何不包含数组的键发出0。减速器将这些相加,以便在检查最终结果时:

db[mr.result].find()

您将看到您的字段名称,其中包含数组值的文档数量(对于任何从不存在数组的文档,都会显示0)。

因此,这应该为您提供哪些字段包含仅具有map-reduce作业的数组类型。

-

只是看一些数据:

db.Product.insert({"a":[1,2,3], "c":[1,2]})
db.Product.insert({"a":1, "b":2})
db.Product.insert({"a":1, "c":[2,3]})

(现在运行上面的“mr =”代码)

db[mr.result].find()
{ "_id" : "_id", "value" : 0 }
{ "_id" : "a", "value" : 1 }
{ "_id" : "b", "value" : 0 }
{ "_id" : "c", "value" : 2 }