Mongodb按版本x.y.z排序

时间:2013-11-07 14:41:49

标签: mongodb sorting

我们的应用程序基于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

2 个答案:

答案 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 }