我们的应用程序基于MongoDB。我们在MongoDB中存储IT资产的“名称”,“版本”和各种属性。我们有一个新的搜索要求,我们需要根据关键字检索最新版本的资产。这里的问题是我的版本号是格式的 x.y.z(即major.minor.maintenance)
基本上,我应该首先按主要版本(desc)排序结果集,然后是次要版本(desc),然后是维护版本(desc)。 例如对于下面给出的版本号: 1.0.10 1.1.0 11.0.0 2.0.1 排序版本应为: 1.0.10 1.2.10 2.0.1 11.0.0 我有可能在Mongo层本身正确排序吗?不幸的是,版本号只是作为单个字符串值存储,而不是x.y.z格式的结构化对象。
提前致谢! 的Zeba
答案 0 :(得分:1)
你需要存储该字段的第二个表示,mongo可以对语义版本进行排序。我选择将每个组件填充到4个字符。
var document = {
version: "1.2.3",
padded_version: "0001.0002.0003",
}
然后你可以对词典字符串索引进行排序。
db.ensureIndex({ padded_version: -1 })
您也可以对每个组件进行位移:
var document = {
version: "1.2.3",
integer_version: 1 << 16 + 2 << 8 + 3,
}
它限制你到256个新版本,但有潜在的溢出问题,等等。我会坚持使用零填充字符串版本。
答案 1 :(得分:0)
我知道这不是最近的问题之一,但我有不同的解决方案。
带有一个投影的选项(较慢):
{$project: {
version: {
major: { $arrayElemAt: [{ $map: { input: { $split: ["$metadata.appVersion", "."] }, as: "vn", in: { $toInt: "$$vn" } } }, 0] },
minor: { $arrayElemAt: [{ $map: { input: { $split: ["$metadata.appVersion", "."] }, as: "vn", in: { $toInt: "$$vn" } } }, 1] },
patch: { $arrayElemAt: [{ $map: { input: { $split: ["$metadata.appVersion", "."] }, as: "vn", in: { $toInt: "$$vn" } } }, 2] }
}
}
带有两个投影的选项(需要总计):
{
$project: {
versionAsArray: {
$map: {
input: {
$split: ["$metadata.appVersion", "."]
},
as: "vn",
in: { $toInt: "$$vn" }
}
}
}
},
{
$project: {
version: {
version: {
major: { $arrayElemAt: ["$versionAsArray", 0] },
minor: { $arrayElemAt: ["$versionAsArray", 1] },
patch: { $arrayElemAt: ["$versionAsArray", 2] },
}
}
}
}
最后你可以使用普通的 $sort: { version: 1 }