猫鼬查询按日期分组

时间:2020-07-11 18:02:49

标签: node.js express mongoose mongodb-query mongoose-schema

我对猫鼬聚合非常陌生,并且具有以下格式的集合

托收文件:

{
  "movie":"Fast and Furious",
  "rating":"Good",
  "ratingTime":"2015-3-06 4:05:10"
},
{
  "movie":"Avengers Infinity Stones",
  "rating":"Very Good",
  "ratingTime":"2020-20-4 22:10:40"
},
{
  "movie":"Mad Max Fury Road",
  "rating":"Average",
  "ratingTime":"2015-3-06 15:23:25"
},
{
  "movie":"Toy story",
  "rating":"Good",
  "ratingTime":"2020-20-4 10:11:02"
}

我想要下面的格式:

[
   {
       "2015-3-06":[{
            "movie":"Fast and Furious",
            "rating":"Good",
            "ratingTime":"2015-3-06 4:05:10"
        },{
            "movie":"Mad Max Fury Road",
            "rating":"Average",
            "ratingTime":"2015-3-06 15:23:25"
        }]
   },
   {
        "2020-20-4":[{
            "movie":"Avengers Infinity Stones",
            "rating":"Very Good",
            "ratingTime":"2020-20-4 22:10:40"
        },{
            "movie":"Toy story",
            "rating":"Good",
            "ratingTime":"2020-20-4 10:11:02"
        }]
   }
]

有人可以帮助我吗,因为我没有任何想法来获取所需格式的输出。非常感谢您的帮助

4 个答案:

答案 0 :(得分:1)

根据您的情况,据我了解,您想使用动态模式键。但是我认为这不是一个好主意,最好使用第一个选项并按日期对它们进行排序,或者,如果您真的想使用它,则可以使用{string: false}。使用 strict 可以使您的整个模式为自由格式,如果您不想使整个模式为自由格式,而是希望其中的一部分,则还可以修改您的模式以使用 mixed

   var movieSchema=newSchema({
       movie:{
          type:String
       },
       rating:{
          type:String
       },
       ratingTime:{
          type:Date,
          default:Date.now()
       }
  })

// var movieSchemaByDate = new Schema({..}, { strict: false }); /*if you are using older versions */
    var movieSchemaByDate = new Schema({..}) 
    var Movie = mongoose.model('Movie', movieSchemaByDate);
    var movie = new Movie({ [date]: movieSchema });
    movie.save();

参考:

mongoose strict

Classify mongoose schema arrays by date

答案 1 :(得分:0)

我对您的问题的解决方案将是以下类型:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var movieSchema=newSchema(
{
    movie:{
        type:String
    },
    rating:{
        type:String
    },
    ratingTime:{
        type:Date,
        default:Date.now()
    }
}
)

var yearSchema = new Schema({
    movieYear:[movieSchema]
});
var books=mongoose.model('books',bookSchema)
module.exports=books;

您可以了解有关Mongoose Subdocuments Mongoose Schemas的更多信息。

答案 2 :(得分:0)

    const aggregate = await Test.aggregate([
      {
        $group: {
          _id: {
            $dateToString: {
              format: '%Y-%m-%d',
              date: '$ratingTime'
            }
          },
          root: {
            $addToSet: '$$ROOT'
          }
        }
      },
      {
        $unwind: {
          path: '$root',
          preserveNullAndEmptyArrays: false
        }
      },
      {
        $group: {
          _id: '$_id',
          movies: {
            $addToSet: '$root'
          }
        }
      }
    ]);
    aggregate.forEach((dateObj) => {
      dateObj[dateObj._id] = dateObj.movies;
      delete dateObj._id;
      delete dateObj.movies;
    });
    console.log(JSON.stringify(aggregate, undefined, 3));

并且由于无法进行动态字段命名(至少我这样认为),因此您需要在获得结果后再进行其余操作。

输出将是:

    [
      {
        '2015-07-03': [
          {
            _id: '5f0a11833456a62a2a91e36a',
            movie: 'Mad Max Fury Road',
            rating: 'Average',
            ratingTime: '2015-07-03T12:23:25.000Z',
            __v: 0
          },
          {
            _id: '5f0a11833456a62a2a91e368',
            movie: 'Fast and Furious',
            rating: 'Good',
            ratingTime: '2015-07-03T12:23:25.000Z',
            __v: 0
          }
        ]
      },
      {
        '2020-05-20': [
          {
            _id: '5f0a11833456a62a2a91e36b',
            movie: 'Toy story',
            rating: 'Good',
            ratingTime: '2020-05-20T07:11:02.000Z',
            __v: 0
          },
          {
            _id: '5f0a11833456a62a2a91e369',
            movie: 'Avengers Infinity Stones',
            rating: 'Very Good',
            ratingTime: '2020-05-20T19:10:40.000Z',
            __v: 0
          }
        ]
      }
    ];

和链接以查看 group by dates in mongodb

https://www.mongodb.com/products/compass

答案 3 :(得分:0)

正如答案之一Eric Asca所述,无法进行动态字段命名。您可以按日期将文档分组。有一件事情要注意,给定数据中的日期格式似乎无效,这就是为什么我使用$substr

const result = await Model.aggregate([
    {
        $group: {
            _id: { $substr: ["$ratingTime", 0, 9] },
            movies: {
                $push: "$$ROOT",
            },
        },
    },
]);

结果看起来像这样。

[
  {
    "_id": "2020-20-4",
    "movies": [
      {
        "_id": "5f0a27a5df68ee25952ae10a",
        "movie": "Avengers Infinity Stones",
        "rating": "Very Good",
        "ratingTime": "2020-20-4 22:10:40",
        "__v": 0
      },
      {
        "_id": "5f0a27a5df68ee25952ae10c",
        "movie": "Toy story",
        "rating": "Good",
        "ratingTime": "2020-20-4 10:11:02",
        "__v": 0
      }
    ]
  },
  {
    "_id": "2015-3-06",
    "movies": [
      {
        "_id": "5f0a27a5df68ee25952ae109",
        "movie": "Fast and Furious",
        "rating": "Good",
        "ratingTime": "2015-3-06 4:05:10",
        "__v": 0
      },
      {
        "_id": "5f0a27a5df68ee25952ae10b",
        "movie": "Mad Max Fury Road",
        "rating": "Average",
        "ratingTime": "2015-3-06 15:23:25",
        "__v": 0
      }
    ]
  }
]

可以轻松将其转换为所需的格式。

const output = result.map(({_id, movies}) => ({[_id]: movies}))