问题
I have a database with a date column in the format dd/mm/yyyy and I'd like to sort by the date in ascending order.
$cursor = $collection->find($filter)->sort(array('date' => 1, 'tripID' => 1));
The date is a string and I'm also filtering on the tripID but that aspect is working. The problem is that at present I'm getting:
01/01/2014
01/02/2014
02/01/2014
02/02/2014
What I would like is:
01/01/2014
02/01/2014
01/02/2014
02/02/2014
Is it possible to achieve this using the query or would it need to be done in the application?
回答1:
Say we have the list given in your question
> db.dates.insertMany([{ "date": "01/01/2014" },
    { "date": "01/02/2014" },
    { "date": "02/01/2014" },
    { "date": "02/02/2014" }])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("5a314eae330cc13d0c9b10c4"),
                ObjectId("5a314eae330cc13d0c9b10c5"),
                ObjectId("5a314eae330cc13d0c9b10c6"),
                ObjectId("5a314eae330cc13d0c9b10c7")
        ]
}
Within MongoDB 3.6 we can use aggregation framework and use the $dateFromString (https://docs.mongodb.com/manual/reference/operator/aggregation/dateFromString/) pipeline operator to convert the string date in to a date and then sort the value:
> db.dates.aggregate([
    { "$project" : { "date" : { "$dateFromString" : { "dateString" : "$date"} } } },
    { "$sort" : { "date" : 1 } }
    ])
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c4"), "date" : ISODate("2014-01-01T00:00:00Z") }
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c5"), "date" : ISODate("2014-01-02T00:00:00Z") }
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c6"), "date" : ISODate("2014-02-01T00:00:00Z") }
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c7"), "date" : ISODate("2014-02-02T00:00:00Z") }
Pior to MongoDB 3.6 there is a workaround to convert your string to a lexicial string date:
> db.dates.aggregate([
    { "$project" : {
        "date" : {
            "$let" : {
                "vars" : { "parts":{ "$split" : [ "$date", "/" ] } },
                "in" : {
                    "$concat" : [
                        { "$arrayElemAt" : [ "$$parts" , 2 ] },
                        "-",
                        { "$arrayElemAt" : [ "$$parts", 1 ] },
                        "-",
                        { "$arrayElemAt" : [ "$$parts", 0 ] } ]
                    }
                }
            }
        }
    },
    { "$sort" : { "date" : 1 } }
])
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c4"), "date" : "2014-01-01" }
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c6"), "date" : "2014-01-02" }
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c5"), "date" : "2014-02-01" }
{ "_id" : ObjectId("5a314eae330cc13d0c9b10c7"), "date" : "2014-02-02" }
I know this is in javascript and you mentioned it was in php, but it's pratically the same, checkout the php documentation (http://php.net/manual/en/mongocollection.aggregate.php)
来源:https://stackoverflow.com/questions/24798948/sort-by-date-string-ascending-on-mongo