【问题标题】:Ordering fields from find query with projection使用投影从查找查询中排序字段
【发布时间】:2012-08-12 04:32:25
【问题描述】:

我有一个 Mongo 查找查询,可以很好地从大型文档中提取特定字段,例如...

db.profiles.find(
  { "profile.ModelID" : 'LZ241M4' },
  {
    _id : 0,
    "profile.ModelID" : 1,
    "profile.AVersion" : 2,
    "profile.SVersion" : 3
  }
);

...这会产生以下输出。请注意文档中 SVersion 是如何出现在 AVersion 之前的,即使我的投影在 SVersion 之前要求 AVersion。

{ "profile" : { "ModelID" : "LZ241M4", "SVersion" : "3.5", "AVersion" : "4.0.3" } }
{ "profile" : { "ModelID" : "LZ241M4", "SVersion" : "4.0", "AVersion" : "4.0.3" } }

...问题是我希望输出是...

{ "profile" : { "ModelID" : "LZ241M4", "AVersion" : "4.0.3", "SVersion" : "3.5" } }
{ "profile" : { "ModelID" : "LZ241M4", "AVersion" : "4.0.3", "SVersion" : "4.0" } }

我需要做什么才能让 Mongo JavaScript shell 以我指定的字段顺序显示我的查询结果?

【问题讨论】:

  • 您的查询在哪里?您是否考虑过使用排序。
  • 我的查询在上面。在一行中: db.profiles.find( { "profile.ModelID" : 'LZ241M4' }, { _id : 0, "profile.ModelID" : 1, "profile.AVersion" : 2, "profile.SVersion" : 3});我没有考虑 sort(),但是对“行”进行排序,我正在尝试对“列”进行排序。
  • 对不起,我不知道我是怎么错过的。我想你已经知道了,但是 mongodb 中有“列”之类的东西。这是您的整个文档还是个人资料是较大文档的子集?
  • "profile" 是较大文档的子文档。我在“行”和“列”周围加上引号,因为我知道 Mongo 是关于文档和字段的,但是为了本次对话的目的,“字段”和“列”在概念上是相似的。我的投影按顺序要求“字段” { _id : 0, "profile.ModelID" : 1, "profile.AVersion" : 2, "profile.SVersion" : 3 } 但 Mongo JavaScript shell 不产生输出以这种方式处理每个文档。我正在寻找一种方法来重新排列每个文档的输出。感谢您的帮助

标签: mongodb


【解决方案1】:

我应用的另一个解决方案如下:

db.profiles
  .find({ "profile.ModelID" : 'LZ241M4' })
  .toArray()
  .map(doc => ({
    profile: {
      ModelID: doc.profile.ModelID,
      AVersion: doc.profile.AVersion,
      SVersion: doc.profile.SVersion
    }
  }))

【讨论】:

    【解决方案2】:

    自 2.6 版(2014 年发布)以来,MongoDB 保留了写入操作后文档字段的顺序 (source)。

    附:如果您使用 Python,您可能会发现 this 很有趣。

    【讨论】:

      【解决方案3】:

      我通过使用别名投影字段来实现它,而不是通过 0 和 1 包含和排除。 试试这个:

      {
      _id : 0,      
      "profile.ModelID" :"$profile.ModelID", 
      "profile.AVersion":"$profile.AVersion",
      "profile.SVersion":"$profile.SVersion"
      }
      

      【讨论】:

      • 这应该是有效的选择答案。谢谢@Gulnur!
      【解决方案4】:

      我现在明白了。您希望返回按“字段”排序的结果,而不是字段的值。

      简单的答案是你不能这样做。也许使用新的聚合框架是可能的。但这似乎只是为了对字段进行排序。

      查找查询中的第二个对象用于包含或排除返回的字段,而不是对它们进行排序。

        {
          _id : 0,               // 0 means exclude this field from results
          "profile.ModelID" : 1, // 1 means include this field in the results
          "profile.AVersion" :2, // 2 means nothing
          "profile.SVersion" :3, // 3 means nothing
        }
      

      最后一点,你不应该这样做,谁在乎字段返回的顺序。 无论字段的顺序如何,您的应用程序都应该能够使用它需要的字段。

      【讨论】:

      • 我不同意你的观点,即按照投影推荐的顺序返回字段是“矫枉过正”,但它的 mongo;我已经习惯了失望。感谢您的帮助。
      • 所以“有序”和“无序”版本代表相同的数据。在 SQL 中,列顺序对于 DataReader 这样的事情可能很重要,您可以在其中按编号选择列。但是使用 MongoDB,您可以有效地获取哈希表。没有排序功能,因为哈希表的键顺序不应该是相关的。但是,我确实喜欢包含编号可以是订单的建议。这绝对值得一张 JIRA 票。 (jira.mongodb.org)
      • 我没有对此进行测试,但从@Bob 得到的输出来看,“2”和“3”确实意味着什么:它们相当于使用“1”。即:零表示不包含,非零表示包含。
      • 从实用的角度来看,纯粹出于个人喜好,在开发或调试期间使用 mongodb shell 时能够对输出字段进行排序会很有帮助。当我执行find() 时,我不总是希望将_id 字段作为第一个输出列。是的,我可能想查看_id,但我首先对其他领域更感兴趣,因此总是在包含_id 时首先看到它可能被视为噪音。
      • @GatesVP:字段顺序相关的一个明显用例是在 mongo shell 中显示 find() 的结果。我已经为此提交了一张票 - jira.mongodb.org/browse/SERVER-12599
      猜你喜欢
      • 2014-05-18
      • 2011-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-31
      相关资源
      最近更新 更多