我如何 select ForerunnerDb 集合中对象的最新版本
How can I select the latest version of an object from a ForerunnerDb collection
我有一个集合,其中包含随时间生成的一系列对象。由于我在同一集合中存储了不同的类型,因此每个对象都有一个 TypeId
和一个 UID
(其中 UID 标识随着时间的推移引用同一实体的对象)。我正在尝试从集合中选择最新的对象,并且 运行 在不手动迭代查询结果的情况下很难掌握如何做到这一点 - 我宁愿避免这样做,因为我认为当集合时它可能会变得昂贵变大了。
例如:
var db; // assigned elsewhere
var col = db.collection("res");
col.primaryKey("resId");
col.insert({
resId: 1,
TypeId: "Person",
UID: "Bob",
Data: {Age: 20, Name:Bob}
});
col.insert({
resId: 2,
TypeId: "Person",
UID: "Bob",
Data: {Age: 25, Name:Bob}
});
col.insert({
resId: 3,
TypeId: "Car",
UID: "TeslaModelX",
Data: {Manufacturer: "Tesla", Owner:"Bob"}
});
col.insert({
resId: 4,
TypeId: "Person",
UID: "Bill",
Data: {Age: 22, Name:Bill}
});
从 col,我希望查询 select 所有具有 TypeId="Person"
的对象 resId
降序排列,即我希望 select 对象 4 和 2 , 按此顺序。
上面的集合是人为设计的,但实际上我希望肯定有 000 个条目,可能有 0000 个,每个 UID 可能有 00 个版本。换句话说,我宁愿不 return 对象的完整集合,分组或以其他方式迭代它。
我尝试了以下方法,但由于 $distinct
运算符是在 $orderBy
运算符之前应用的,所以这无济于事:
col.find(
{
TypeId : {$eq : "Person"}
$distinct: { UID: 1}
},
{
$orderBy: {
resId : -1
}
}
);
我想我应该能够使用 $groupBy
、$limit
和 $aggregate
子句来识别每个组所需的 ID,然后使用子查询来查找精确的(非聚合的)元素,但到目前为止我还没有设法做我想做的事。有什么想法吗?
我当前的解决方案是在我的对象中包含一个 Deleted
属性,并在我插入新条目之前将它设置为数据库中所有现有的未删除对象的 true。这让我可以做我想做的事,但也可以阻止我,例如,在已知时间范围或类似时间范围内选择最好的。
您可以这样做:
var tmpObj = {};
col.sort({resId: -1}, coll.find({
"TypeId": "Person"
})).filter(function (doc) {
return col._match(doc, {
$distinct: {
UID: 1
}
}, {}, 'and', tmpObj);
});
它有点脏,因为它没有整齐地包含在单个命令中,但它和您在 ForerunnerDB 中得到的一样干净v1.x。
版本 2 将有一个新的查询管道系统,它允许这种用法,就像这样:
col.pipeline()
.find({"TypeId": "Person"})
.orderBy({"resId": 1})
.distinct({"UID": 1})
.then(function (err, data) {
console.log(data);
});
来源:我是 ForerunnerDB 的开发者。
我有一个集合,其中包含随时间生成的一系列对象。由于我在同一集合中存储了不同的类型,因此每个对象都有一个 TypeId
和一个 UID
(其中 UID 标识随着时间的推移引用同一实体的对象)。我正在尝试从集合中选择最新的对象,并且 运行 在不手动迭代查询结果的情况下很难掌握如何做到这一点 - 我宁愿避免这样做,因为我认为当集合时它可能会变得昂贵变大了。
例如:
var db; // assigned elsewhere
var col = db.collection("res");
col.primaryKey("resId");
col.insert({
resId: 1,
TypeId: "Person",
UID: "Bob",
Data: {Age: 20, Name:Bob}
});
col.insert({
resId: 2,
TypeId: "Person",
UID: "Bob",
Data: {Age: 25, Name:Bob}
});
col.insert({
resId: 3,
TypeId: "Car",
UID: "TeslaModelX",
Data: {Manufacturer: "Tesla", Owner:"Bob"}
});
col.insert({
resId: 4,
TypeId: "Person",
UID: "Bill",
Data: {Age: 22, Name:Bill}
});
从 col,我希望查询 select 所有具有 TypeId="Person"
的对象 resId
降序排列,即我希望 select 对象 4 和 2 , 按此顺序。
上面的集合是人为设计的,但实际上我希望肯定有 000 个条目,可能有 0000 个,每个 UID 可能有 00 个版本。换句话说,我宁愿不 return 对象的完整集合,分组或以其他方式迭代它。
我尝试了以下方法,但由于 $distinct
运算符是在 $orderBy
运算符之前应用的,所以这无济于事:
col.find(
{
TypeId : {$eq : "Person"}
$distinct: { UID: 1}
},
{
$orderBy: {
resId : -1
}
}
);
我想我应该能够使用 $groupBy
、$limit
和 $aggregate
子句来识别每个组所需的 ID,然后使用子查询来查找精确的(非聚合的)元素,但到目前为止我还没有设法做我想做的事。有什么想法吗?
我当前的解决方案是在我的对象中包含一个 Deleted
属性,并在我插入新条目之前将它设置为数据库中所有现有的未删除对象的 true。这让我可以做我想做的事,但也可以阻止我,例如,在已知时间范围或类似时间范围内选择最好的。
您可以这样做:
var tmpObj = {};
col.sort({resId: -1}, coll.find({
"TypeId": "Person"
})).filter(function (doc) {
return col._match(doc, {
$distinct: {
UID: 1
}
}, {}, 'and', tmpObj);
});
它有点脏,因为它没有整齐地包含在单个命令中,但它和您在 ForerunnerDB 中得到的一样干净v1.x。
版本 2 将有一个新的查询管道系统,它允许这种用法,就像这样:
col.pipeline()
.find({"TypeId": "Person"})
.orderBy({"resId": 1})
.distinct({"UID": 1})
.then(function (err, data) {
console.log(data);
});
来源:我是 ForerunnerDB 的开发者。