Mongo Groupby Aggregate基于" Key"不值

时间:2017-03-17 08:03:15

标签: node.js mongodb mongoose mongodb-query loopbackjs

我坚持使用mongo查询。我有一个mongo集合结构,我现在无法修改,因为它是非常大的数据。

我需要从集合中执行一些结果,所以尝试各种方法来获得它。

这是我的集合json架构: -

{
    "date": "2017-01-01T00:00:00.000Z",
    "bob":"P",
    "jacob":"P",
    "wilson":"A",
    "dev":"SL"
},
{
    "date": "2017-01-02T00:00:00.000Z",
    "bob":"P",
    "jacob":"A",
    "wilson":"A",
    "dev":"SL"
},
{
    "date": "2017-01-03T00:00:00.000Z",
    "bob":"P",
    "jacob":"P",
    "wilson":"A",
    "dev":"SL"
},
{
    "date": "2017-01-04T00:00:00.000Z",
    "shashikant":"P",
    "jacob":"P",
    "wilson":"SL",
    "dev":"SL"
}
....

作为输出我正在寻找以下类型的结构: -

from 1st jan 2017 to 30th jan 2017

    bob      P      17
    bob      A      2
    wilson   P      10
    dev      SL.    1
    .....

我在后端使用loopback但仍然可以使用普通的mongodb查询来获取输出。

请帮忙

1 个答案:

答案 0 :(得分:1)

MongoDB仅允许对数组进行$ unwind。但是你可以用一个简单的mapReduce来实现你想要的东西:



//Define the time frame here
var from = new Date('2015-01-01T00:00:00.000Z');
var to = new Date('2025-01-01T00:00:00.000Z');

db.getCollection('test').mapReduce(function () {
		var keys = Object.keys(this);

		//If there is no date found on a record, simply skip
		if (!this.date) {
			return;
		}

		var date = new Date(this.date);

		//Skip the records that do not fit into [form; to] interval
		if (!(date >= from && date <= to)) {
			return;
		}

		for (var i = 0; i < keys.length; i++) {
			var key = keys[i];

			//Emit each combination of key and value
			if (key !== 'date' && key !== '_id') {
				emit({key: key, value: this[key]}, {count: 1});
			}
		}
	},

	function (key, values) {
		var reduced = {count: 0};

		for (var i = 0; i < values.length; i++) {
			var value = values[i];

			//Simply counting the combinations here
			reduced.count += value.count;
		}

		return reduced;
	},
	{
		//Passing the dates to mongo
		//so 'from' and 'to' will be avail in map, reduce and finalize
		scope: {from: from, to: to},
		finalize: function (key, reducedValue) {
			//Changing the data structure just for a convenience
			return {
				propertyName: key.key,
				propertyValue: key.value,
				from: from,
				to: to,
				count: reducedValue.count
			};
		},
		out: {inline: 1}
	}
);
&#13;
&#13;
&#13;

我在Mongo控制台中对此进行了测试,但mongo原生Node.js和mongoose也支持map-reduced。