【问题标题】:Sort in embedded collection in MongoDB在 MongoDB 中的嵌入式集合中排序
【发布时间】:2016-08-10 12:42:01
【问题描述】:

我正在使用 MongoDb 3.2.8。下面是我的测试集合,其中包含 2 个存储银行帐户余额信息的文档。两个余额(期末余额和可用余额存储在每个帐户的 2 种货币 GBP 和 EUR 中。

    /* 1 */
    {
        "_id" : "100001-AT611904300234101001",
        "agref" : "100001",
        "acref" : "AT611904300234101001",
        "bal" : [ 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLAV"
                    }
                },
                "amt" : {
                    "value" : "6452",
                    "ccy" : "EUR"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }, 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLBD"
                    }
                },
                "amt" : {
                    "value" : "6452",
                    "ccy" : "EUR"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }, 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLAV"
                    }
                },
                "amt" : {
                    "value" : "5727.8275199999998221755959093570709228515625",
                    "ccy" : "GBP"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }, 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLBD"
                    }
                },
                "amt" : {
                    "value" : "5727.8275199999998221755959093570709228515625",
                    "ccy" : "GBP"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }
        ]
    }

    /* 2 */
    {
        "_id" : "100001-AT522904300234201001",
        "agref" : "100001",
        "acref" : "AT522904300234201001",
        "bal" : [ 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLAV"
                    }
                },
                "amt" : {
                    "value" : "72579.83178142391261644661426544189453125",
                    "ccy" : "EUR"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }, 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLBD"
                    }
                },
                "amt" : {
                    "value" : "72579.83178142391261644661426544189453125",
                    "ccy" : "EUR"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }, 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLAV"
                    }
                },
                "amt" : {
                    "value" : "64433.471462276895181275904178619384765625",
                    "ccy" : "GBP"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }, 
            {
                "tp" : {
                    "cdOrPrtry" : {
                        "cd" : "CLBD"
                    }
                },
                "amt" : {
                    "value" : "64433.471462276895181275904178619384765625",
                    "ccy" : "GBP"
                },
                "cdtDbtInd" : "CRDT",
                "dt" : {
                    "dt" : "2016-06-30"
                }
            }
        ]
    }

我想做的是对余额类型“CLBD”和货币“EUR”的测试集合进行排序。

我尝试了以下方法:

    db.test.aggregate([
         {$unwind: "$bal"}
        ,{$match: {"bal.amt.ccy": "EUR", "bal.tp.cdOrPrtry.cd":"CLBD"}}
        ,{$sort: {"bal.amt.value":-1}}
        ]);

输出在某种程度上很好,即它对数据进行排序,但它从原始文档中删除了某些字段,即英镑余额、CLAV 余额等:

/* 1 */
{
    "_id" : "100001-AT522904300234201001",
    "agref" : "100001",
    "acref" : "AT522904300234201001",
    "bal" : {
        "tp" : {
            "cdOrPrtry" : {
                "cd" : "CLBD"
            }
        },
        "amt" : {
            "value" : "72579.83178142391261644661426544189453125",
            "ccy" : "EUR"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
            "dt" : "2016-06-30"
        }
    }
}

/* 2 */
{
    "_id" : "100001-AT611904300234101001",
    "agref" : "100001",
    "acref" : "AT611904300234101001",
    "bal" : {
        "tp" : {
            "cdOrPrtry" : {
                "cd" : "CLBD"
            }
        },
        "amt" : {
            "value" : "6452",
            "ccy" : "EUR"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
            "dt" : "2016-06-30"
        }
    }
}

请指教。

【问题讨论】:

  • 匹配正在过滤数据。所以 GBP 和 CLAV 没有被选中。

标签: mongodb sorting


【解决方案1】:

您可以使用$$ROOT 引用原始文档,但它会稍微改变结果的结构:

db.test.aggregate([
  { 
    $project: {
      bal: { $filter: {
        input: "$bal",
        as: "bal",
        cond: { $and: [
          { $eq: [ "$$bal.amt.ccy", "EUR" ] },
          { $eq: [ "$$bal.tp.cdOrPrtry.cd", "CLBD" ] }
        ] }
      } },
      doc: "$$ROOT"
    } 
  },
  { 
    $unwind: "$bal" 
  },
  {
    $sort: { "bal.amt.value": -1 }
  }
]);

将产生一个有序的元素列表,包括包含整个文档的 doc 字段:

/* 1 */
{
  "_id" : "100001-AT522904300234201001",
  "bal" : {
    "tp" : {
      "cdOrPrtry" : {
        "cd" : "CLBD"
      }
    },
    "amt" : {
      "value" : "72579.83178142391261644661426544189453125",
      "ccy" : "EUR"
    },
    "cdtDbtInd" : "CRDT",
    "dt" : {
      "dt" : "2016-06-30"
    }
  },
  "doc" : {
    "_id" : "100001-AT522904300234201001",
    "agref" : "100001",
    "acref" : "AT522904300234201001",
    "bal" : [
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLAV"
          }
        },
        "amt" : {
          "value" : "72579.83178142391261644661426544189453125",
          "ccy" : "EUR"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      },
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLBD"
          }
        },
        "amt" : {
          "value" : "72579.83178142391261644661426544189453125",
          "ccy" : "EUR"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      },
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLAV"
          }
        },
        "amt" : {
          "value" : "64433.471462276895181275904178619384765625",
          "ccy" : "GBP"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      },
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLBD"
          }
        },
        "amt" : {
          "value" : "64433.471462276895181275904178619384765625",
          "ccy" : "GBP"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      }
    ]
  }
}

/* 2 */
{
  "_id" : "100001-AT611904300234101001",
  "bal" : {
    "tp" : {
      "cdOrPrtry" : {
        "cd" : "CLBD"
      }
    },
    "amt" : {
      "value" : "6452",
      "ccy" : "EUR"
    },
    "cdtDbtInd" : "CRDT",
    "dt" : {
      "dt" : "2016-06-30"
    }
  },
  "doc" : {
    "_id" : "100001-AT611904300234101001",
    "agref" : "100001",
    "acref" : "AT611904300234101001",
    "bal" : [
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLAV"
          }
        },
        "amt" : {
          "value" : "6452",
          "ccy" : "EUR"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      },
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLBD"
          }
        },
        "amt" : {
          "value" : "6452",
          "ccy" : "EUR"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      },
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLAV"
          }
        },
        "amt" : {
          "value" : "5727.8275199999998221755959093570709228515625",
          "ccy" : "GBP"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      },
      {
        "tp" : {
          "cdOrPrtry" : {
            "cd" : "CLBD"
          }
        },
        "amt" : {
          "value" : "5727.8275199999998221755959093570709228515625",
          "ccy" : "GBP"
        },
        "cdtDbtInd" : "CRDT",
        "dt" : {
          "dt" : "2016-06-30"
        }
      }
    ]
  }
}

【讨论】:

  • 优秀。这就是我一直在寻找的。​​span>
猜你喜欢
  • 1970-01-01
  • 2012-05-09
  • 2016-06-23
  • 2013-11-12
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多