看来你的问题明确要求“获取每个第 n 个实例”,这似乎是一个非常明确的问题。
查询操作如.find()
实际上只能“按原样”返回文档,但投影中的一般字段“选择”和运算符(例如位置性的$ http://docs.mongodb.org/manual/reference/operator/projection/positional/匹配运算符或$elemMatch http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/允许单个匹配的数组元素。
当然有$slice http://docs.mongodb.org/manual/reference/operator/projection/slice/,但这只允许在数组上进行“范围选择”,因此同样不适用。
可以修改服务器上结果的“唯一”事物是.aggregate() http://docs.mongodb.org/manual/reference/method/db.collection.aggregate/ and .mapReduce() http://docs.mongodb.org/manual/reference/method/db.collection.mapReduce/。前者不能以任何方式“很好地处理”数组的“切片”,至少不是“n”个元素。然而,由于 mapReduce 的“function()”参数是基于 JavaScript 的逻辑,因此您有更多的空间可以使用。
对于分析过程,并且“仅”出于分析目的,只需使用 mapReduce 过滤数组内容.filter() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter:
db.collection.mapReduce(
function() {
var id = this._id;
delete this._id;
// filter the content of "instances" to every 3rd item only
this.instances = this.instances.filter(function(el,idx) {
return ((idx+1) % 3) == 0;
});
emit(id,this);
},
function() {},
{ "out": { "inline": 1 } } // or output to collection as required
)
此时它实际上只是一个“JavaScript 运行器”,但如果这只是用于分析/测试,那么这个概念通常没有任何问题。当然,输出并不“完全”是文档的结构,但它与 mapReduce 所能获得的最接近的传真一样。
我在这里看到的另一个建议需要创建一个新的集合,其中所有项目都“非规范化”,并从数组中插入“索引”作为唯一的一部分_id
钥匙。这可能会产生一些你可以直接查询的东西,但是对于“每n个项目”你仍然需要做:
db.resultCollection.find({
"_id.index": { "$in": [2,5,8,11,14] } // and so on ....
})
因此,计算并提供“每第n项”的索引值,以获得“每第n项”。所以这似乎并没有真正解决所提出的问题。
如果输出形式似乎更适合您的“测试”目的,那么对这些结果的更好的后续查询将使用聚合管道,其中$redact http://docs.mongodb.org/manual/reference/operator/aggregation/redact/
db.newCollection([
{ "$redact": {
"$cond": {
"if": {
"$eq": [
{ "$mod": [ { "$add": [ "$_id.index", 1] }, 3 ] },
0 ]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
这至少使用了与应用的“逻辑条件”大致相同的“逻辑条件”.filter()
之前只选择“第 n 个索引”项,而不列出所有可能的索引值作为查询参数。