如何从数组中返回两个非连续的索引值

时间:2015-09-24 02:29:24

标签: mongodb mongodb-query aggregation-framework

Hope to get help, I must find two data with array. mongodb version 2.6.6

测试声明:

db.test.insert({"student":[1,2,3,4,5]})

知道两个索引1和3,可以使用语句查询,查找数组学生[1]和学生[3]的值。 我只知道查询一个值,这是以下语句

db.test.find({},{'student': {'$slice':[2,2]}})

我的问题是如何通过语句查询找到student array 2的值。 我想输出值2,4。

1 个答案:

答案 0 :(得分:0)

目前不支持从$slice操作中不连续的数组中获取两个索引位置,据我所知,目前并不是直接上书。

MongoDB的未来版本将同时具有$slice$concatArrays功能,可以完全按照您的要求执行:

db.test.aggregate([
    { "$project": { 
        "student": { 
            "$concatArrays": [
                { "$slice": [ "$student",1,1 ] },
                { "$slice": [ "$student",3,1 ] }
            ]

        } 
    }}
])

将完全按照您的要求输出:

{ "_id" : ObjectId("56039585091d337d88627dfc"), "student" : [ 2, 4 ] }

这对我现在正在运行开发版本(3.1.7)。

目前你仍然遇到两个问题,因为有一些一般的" hackery"你现在可以在聚合框架中做"值"但" index"是不可能的。数组。

在shell中,基本概念是运行每个查询并构建一个" hash"匹配的文档_id的值,并且基本上附加到每个索引位置包含的每个数组。

对于shell来说并不是一个实际的例子,但是有一些东西可以通过使用" parallel"来证明。查询和构建"哈希"看起来像使用nedb作为内存存储的集合,以及node.async作为帮助程序的并行执行:

var async = require('async'),
    mongodb = require('mongodb'),
    DataStore = require('nedb'),
    MongoClient = mongodb.MongoClient,
    store = new DataStore();

MongoClient.connect('mongodb://localhost/test',function(err,db) {

  var collection = db.collection('test');

  async.parallel(
    [
      function(callback) {
        var stream = collection.find({},{ "student": { "$slice": [1,1] } });

        stream.on("err",callback);

        stream.on("end",callback);

        stream.on("data",function(data) {
          stream.pause();
          data.orig = data._id;
          delete data._id;
          store.update(
            { "orig": data.orig.toString() },
            { "$push": { "student": { "$each": data.student } } },
            { "upsert": true },
            function(err) {
              if (err) callback(err);
              stream.resume()
            }
          );
        });
      },

      function(callback) {
        var stream = collection.find({},{ "student": { "$slice": [3,1] } });

        stream.on("err",callback);

        stream.on("end",callback);

        stream.on("data",function(data) {
          stream.pause();
          data.orig = data._id;
          delete data._id;
          store.update(
            { "orig": data.orig.toString() },
            { "$push": { "student": { "$each": data.student } } },
            { "upsert": true },
            function(err) {
              if (err) callback(err);
              stream.resume()
            }
          );
        });
      }
    ],
    function(err) {
      if (err) throw err;
      store.find({},function(err,results) {
        console.log(results);
        db.close();
      });
    }
  )

});

这会给你很多相同的结果(某种程度上):

[ { orig: '56039585091d337d88627dfc',
    student: [ 2, 4 ],
    _id: 'srzH9Z7zIYdET2KJ' } ]

请注意," parallel"由于两个查询都在同一时间运行,因此对性能有好处,如果您需要保留索引顺序,那么您需要连续运行或在" series"。

如果您需要此类功能,可以使用后一种方法或等待下一版本的MongoDB。如果您的应用程序需要此功能尚未准备好进行生产,那么开始使用开发版本可能值得花时间为可用的新功能做好准备。