【问题标题】:Sorting MongoDB result by another MongoDB result is returning [null, null, null]按另一个 MongoDB 结果排序 MongoDB 结果返回 [null, null, null]
【发布时间】:2021-11-20 04:21:39
【问题描述】:

我正在执行两个 MongoDB 查询,然后我想同步结果数组,以确保它们的顺序相同。

第一个数组是一组 (20) 个问题 ID(这是正确的顺序):

q_id_arr: [
   "5f86da2d37e3d200040ba523",
   "5f86b6ce37e3d200040ba4c6",
   "5ffc4abea04f3c0004e46cf3",
   "5f86b66537e3d200040ba4c5",
   "5f87f368554f370004ed17b4",
   "5f86e48c37e3d200040ba53c",
   "5ffc4dc4a04f3c0004e46d0b",
   "5f86e19037e3d200040ba534",
   "5f86aaa237e3d200040ba49b",
   "5ffc479ba04f3c0004e46ce0",
   "5f86b9dc37e3d200040ba4d2",
   "5f85828e0e1bd30004361430",
   "5f8700c937e3d200040ba548",
   "5f86d81737e3d200040ba51c",
   "5f8708d237e3d200040ba568",
   "5f87060d37e3d200040ba55c",
   "5f857dac0e1bd3000436141c",
   "5f85703e0e1bd300043613ec",
   "5f87e9d4554f370004ed178e",
   "5f8073c04ad88e00041f015f"
]

第二个数组是一组 (20) 个与问题 ID 相关的结果:

team_trends: [
   {
      "_id":"5f87e9d4554f370004ed178e",
      "positive":0.93,
      "engaged":0.558
   },
   {
      "_id":"5f86e19037e3d200040ba534",
      "positive":0.585,
      "engaged":0.567
   },
   {
      "_id":"5f85828e0e1bd30004361430",
      "positive":0.7,
      "engaged":0.666
   },
   {
      "_id":"5f8073c04ad88e00041f015f",
      "positive":0.31,
      "engaged":0.30999999999999994
   },
   {
      "_id":"5f87f368554f370004ed17b4",
      "positive":0.5449999999999999,
      "engaged":0.57
   },
   {
      "_id":"5f86b6ce37e3d200040ba4c6",
      "positive":0.855,
      "engaged":0.46599999999999997
   },
   {
      "_id":"5f857dac0e1bd3000436141c",
      "positive":0.92,
      "engaged":0.524
   },
   {
      "_id":"5f85703e0e1bd300043613ec",
      "positive":0.15,
      "engaged":0.39
   },
   {
      "_id":"5f86aaa237e3d200040ba49b",
      "positive":0.15000000000000002,
      "engaged":0.584
   },
   {
      "_id":"5f86b66537e3d200040ba4c5",
      "positive":0.37,
      "engaged":0.386
   },
   {
      "_id":"5f86e48c37e3d200040ba53c",
      "positive":0.615,
      "engaged":0.548
   },
   {
      "_id":"5ffc479ba04f3c0004e46ce0",
      "positive":0.42000000000000004,
      "engaged":0.583
   },
   {
      "_id":"5f86b9dc37e3d200040ba4d2",
      "positive":0.68,
      "engaged":0.662
   },
   {
      "_id":"5f86d81737e3d200040ba51c",
      "positive":0.03,
      "engaged":0.516
   },
   {
      "_id":"5f87060d37e3d200040ba55c",
      "positive":0.14,
      "engaged":0.454
   },
   {
      "_id":"5f86da2d37e3d200040ba523",
      "positive":0.47,
      "engaged":0.41500000000000004
   },
   {
      "_id":"5f8708d237e3d200040ba568",
      "positive":0.17,
      "engaged":0.76
   },
   {
      "_id":"5ffc4dc4a04f3c0004e46d0b",
      "positive":0.395,
      "engaged":0.53
   },
   {
      "_id":"5ffc4abea04f3c0004e46cf3",
      "positive":0.365,
      "engaged":0.679
   },
   {
      "_id":"5f8700c937e3d200040ba548",
      "positive":0.93,
      "engaged":0.6980000000000001
   }
]

我想将team_trends重组为与q_id_arr相同的顺序

这是我正在使用的代码(遵循this SO Answer):

let c = [];
q_id_arr.forEach((q_oid => c.push(team_trends.find((obj => obj._id == q_oid)))));

但是,当我打印 console.log("the result of c"+ c) 时,我得到了这个结果:

the result of c: [null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]

这是正确的方法吗?任何建议表示赞赏!

更多详情:

在这一步之前,我通过映射aggregate 结果获得了q_id_arr,如下所示:

let q_id_arr = await user_trends.map(({ question_oid }) => question_oid)

当我测试console.log(typeof q_id_arr) 时,它返回了object

如何对对象进行排序??

【问题讨论】:

  • 请注意——我确实尝试使用mongoose.Types.ObjectId( ) 进行排序,但没有任何区别
  • 你能试试这个代码吗:q_id_arr.forEach((q_oid => c.push(team_trends.find((obj => obj._id.equals(q_oid)))))); 我通过复制粘贴确切的数组来尝试你的代码,你的代码似乎工作正常。这意味着除了代码逻辑之外还有其他问题。 @izzi
  • 感谢@ShabbirAhmad - 我认为问题是在此之前的步骤,因为我使用映射函数创建了数组:let q_id_arr = await user_trends.map(({ question_oid }) => question_oid)
  • @Izzi 如果您使用的是猫鼬,那么它已经从聚合函数返回了一个数组。我仍然认为问题在于您的比较。检查这个:stackoverflow.com/questions/11637353/…
  • @Izzi 使用这个user_trends.forEach((user => c.push(team_trends.find((obj => obj._id.toString() === user.question_oid.toString())))));

标签: javascript mongodb sorting


【解决方案1】:

解决问题的最终代码。

user_trends.forEach((user => c.push(team_trends.find((obj => obj._id.toString() === user.question_oid.toString())))));

这里有几点需要注意:

  1. 如果您使用的是 mongoose,那么它已经从聚合函数返回了一个数组。
  2. Mongoose 在其核心使用 MongoDB NodeJs 本机驱动程序。在核心驱动 ObjectId 中有一个函数.equals(otherId)。最好使用此函数进行 id 比较。

参考资料:

  1. Comparing mongoose _id and strings
  2. .aggregate(...).toArray is not a function
  3. https://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html#equals

【讨论】:

  • 虽然 id 在控制台中看起来都一样,但实际上它们是不同的。标准化变量类型(即:toString())应该是故障排除技术。
【解决方案2】:

您可以尝试使用数组map 方法:

let sorted_team_trends = q_id_arr.map( q => team_trends.find(t => t._id === q) );

假设这两个数组被定义为这样的字段:

let q_id_arr = [
        "5f86da2d37e3d200040ba523",
        "5f86b6ce37e3d200040ba4c6",
        "5ffc4abea04f3c0004e46cf3",
        ...
];

let team_trends = [
        {
                "_id" : "5f87e9d4554f370004ed178e",
                "positive" : 0.93,
                "engaged" : 0.558
        },
        {
                "_id" : "5f86e19037e3d200040ba534",
                "positive" : 0.585,
                "engaged" : 0.567
        },
        ...
]

【讨论】:

  • 谢谢你——我刚试过,结果也是[null, null, null,...]
  • 我尝试使用您在问题中发布的两个数组(作为两个 JavaScript 数组字段)作为两个数组字段;我得到正确的排序结果。这两个数组是否定义为变量?还是文件?这两个数组的来源是什么?
  • 好的,我想你已经解决了这个问题......在这一步之前,我使用了一个地图函数来创建q_id_arr,当我尝试typeof q_id_arr时它返回object跨度>
  • 查看编辑后的答案以及我在您的问题帖子中使用的示例输入。
  • 是的,您的代码有效,但在我的情况下不行,因为我创建了这样的数组:let q_id_arr = await user_trends.map(({ question_oid }) => question_oid)
猜你喜欢
  • 2020-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-06
  • 1970-01-01
  • 2015-11-18
  • 2019-10-14
相关资源
最近更新 更多