查询语言
查询语言
当引入关系模型时,关系模型包含了一种查询数据的新方法:
function getSharks() {
var sharks = [];
for (var i = 0; i < animals.length; i++) {
if (animals[i].family === "Sharks") {
sharks.push(animals[i]);
}
}
return sharks;
}
在关系代数中:$sharks = σ_{family = “sharks”}(animals)$,只返回符合条件的动物,family=“shark”。定义
> SELECT * FROM animals WHERE family ='Sharks';
命令式语言告诉计算机以特定顺序执行某些操作。可以想象一下,逐行地遍历代码,评估条件,更新变量,并决定是否再循环一遍。在声明式查询语言(如
声明式查询语言是迷人的,因为它通常比命令式
最后,声明式语言往往适合并行执行。现在,
MapReduce 查询
最好举例来解释
SELECT
date_trunc('month', observation_timestamp) AS observation_month,
sum(num_animals) AS total_animals
FROM observations
WHERE family = 'Sharks'
GROUP BY observation_month;
date_trunc('month',timestamp)
函数用于确定包含
db.observations.mapReduce(
function map() {
var year = this.observationTimestamp.getFullYear();
var month = this.observationTimestamp.getMonth() + 1;
emit(year + "-" + month, this.numAnimals);
},
function reduce(key, values) {
return Array.sum(values);
},
{
query: {
family: "Sharks"
},
out: "monthlySharkReport"
}
);
- 可以声明式地指定只考虑鲨鱼种类的过滤器(这是一个针对
MapReduce 的特定于MongoDB 的扩展) 。 - 每个匹配查询的文档都会调用一次
JavaScript 函数map
,将this
设置为文档对象。 map
函数发出一个键(包括年份和月份的字符串,如"2013-12"
或"2014-1"
)和一个值(该观察记录中的动物数量) 。map
发出的键值对按键来分组。对于具有相同键(即,相同的月份和年份)的所有键值对,调用一次reduce
函数。reduce
函数将特定月份内所有观测记录中的动物数量相加。- 将最终的输出写入到
monthlySharkReport
集合中。
例如,假设
[
{
observationTimestamp: Date.parse("Mon, 25 Dec 1995 12:34:56 GMT"),
family: "Sharks",
species: "Carcharodon carcharias",
numAnimals: 3
},
{
observationTimestamp: Date.parse("Tue, 12 Dec 1995 16:17:18 GMT"),
family: "Sharks",
species: "Carcharias taurus",
numAnimals: 4
}
];
对每个文档都会调用一次emit("1995-12",3)
和 emit("1995-12",4)
。随后,以 reduce("1995-12",[3,4])
调用
db.observations.aggregate([
{ $match: { family: "Sharks" } },
{
$group: {
_id: {
year: { $year: "$observationTimestamp" },
month: { $month: "$observationTimestamp" }
},
totalAnimals: { $sum: "$numAnimals" }
}
}
]);
聚合管道语言与