在MongoDB中的嵌入式集合中排序

时间:2016-08-10 12:42:02

标签: mongodb sorting

我正在使用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}}
        ]);

输出在某种程度上是正常的,即它对数据进行排序,但它从原始文档中删除某些字段,即GBP中的余额,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"
        }
    }
}

请建议。

1 个答案:

答案 0 :(得分: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"
        }
      }
    ]
  }
}