Mongodb聚集对查找结果进行排序,并添加字段索引号

时间:2019-01-31 05:52:32

标签: mongodb lookup

已执行汇总。

我通过查找获得了结果,但是我需要进行排序。

此外,我想为结果值分配一个索引。

CollectionA:

{
    "_id" : ObjectId("5a6cf47415621604942386cd"),
    "contents" : [
             ObjectId("AAAAAAAAAAAAAAAAAAAAAAAA"),
             ObjectId("BBBBBBBBBBBBBBBBBBBBBBBB")
    ],
    "name" : "jason"
}

CollectionB:

{
    "_id" : ObjectId("AAAAAAAAAAAAAAAAAAAAAAAA")
    "title" : "a title",
    "date" : 2018-01-02
},
{
    "_id" : ObjectId("BBBBBBBBBBBBBBBBBBBBBBBB")
    "title" : "a title",
    "date" : 2018-01-01
}

查询:

db.getCollection('A').aggregate([
{
    $match : { "_id" : ObjectId("5a6cf47415621604942386cd") }
},
{
    $lookup : {
        from: "B",
        localField: "contents",
        foreignField: "_id",
        as: "item"

    }
},
{ $sort: { "item.date" : -1 } }
]);

想要的结果:

    {
        "_id" : ObjectId("5a6cf47415621604942386cd"),
        "contents" : [
         {
            "_id" : ObjectId("BBBBBBBBBBBBBBBBBBBBBBBB")
            "title" : "a title",
            "date" : 2018-01-01,
            "index" : 0
        },
        {
            "_id" : ObjectId("AAAAAAAAAAAAAAAAAAAAAAAA")
            "title" : "a title",
            "date" : 2018-01-02,
            "index" : 1
        }],
        "name" : "jason"
    }
  

当前问题不适用于排序。

     

而且我不知道如何指定索引。

2 个答案:

答案 0 :(得分:0)

一种解决方法是展开数组,对其进行排序,然后将其归组

db.A.aggregate([
  {
    $match: {
      "_id": ObjectId("5a6cf47415621604942386cd")
    }
  },
  {
    $lookup: {
      from: "B",
      localField: "contents",
      foreignField: "_id",
      as: "item"
    }
  },
  {
    $unwind: "$item"
  },
  {
    $sort: {
      "item.date": -1
    }
  },
  {
    $group: {
      _id: "$_id",
      contents: {
        $push: "$item"
      }
    }
  }
])

另一种方法是(仅在日期字段对应于文档创建日期时才适用)

db.A.aggregate([
  {
    $match: {
      "_id": ObjectId("5a6cf47415621604942386cd")
    }
  },
  {
    $lookup: {
      from: "B",
      localField: "contents",
      foreignField: "_id",
      as: "item"
    }
  },
  {
    $sort: {
      "item": -1
    }
  }
])

基本上,此排序基于_id进行,并且由于_id是使用创建日期创建的,因此应进行相应的排序。

答案 1 :(得分:0)

可以在Aggregation下面。为了您想要的结果。

db.CollectionA.aggregate([
  {
    $match: { "_id": ObjectId("5a6cf47415621604942386cd") }
  },
  {
    $lookup: {
      from: "CollectionB",
      let: { contents: "$contents" },
      pipeline: [
        {
          $match: { $expr: { $in: ["$_id", "$$contents"] } }
        },
        { $sort: { date: 1 } }
      ],
      as: "contents"
    }
  },
  {
    $project: {
      contents: {
        $map: {
          input: { $range: [0, { $size: "$contents" }, 1 ] },
          as: "element",
          in: {
            $mergeObjects: [
              { index: "$$element" },
              { $arrayElemAt: [ "$contents", "$$element" ]}
            ]
          }
        }
      }
    }
  }
])