Mongo - Java - get all documents sort string date as date

瘦欲@ 提交于 2020-01-25 06:45:12

问题


Just wondering what the best approach is. The following code needs to be able to sort a string date as a date value in descending order, but with pagination.

documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending("ReceivedDate"));

Aside from the sort not working the rest of the line works a treat. Im still getting used to using Mongo. thought it best to find out the right way, or good way, of doing things. Get into good habbits early.

The difference to the links I found was im adding in pagination.

There are a few links I looked at but not 100% certain what I need when I was using find. Sort by date string (ascending) on Mongo MongoDB sorting date string (mm/dd/yyyy)

A typical document we are trying to paginate with descending sort is

{
"_id" : ObjectId("5ddc80b3adbe1d0001bc50f7"),
"ReceivedDate" : "20/12/2019",
"ReceivedTime" : "08:00:00",
"batch_id" : "112233",
"EventMessage" : "SUCCESS",
"Observations" : 1,
"DataSet" : "xxxx",
"SetType" : "yyy",
"SetName" : "yyyxxx",

}

Many thanks in advance, Russell


回答1:


The following code needs to be able to sort a string date as a date value in descending order, but with pagination.

documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending("ReceivedDate"));

Aside from the sort not working the rest of the line works a treat.

You have to use the ReceivedDate (string format) in the format of "YYYY-MM-DD" (string format) to be able to sort it, or use a date field with the values from the string.

The way to do it is use aggregation; for example:

The document with string date: { _id: 1, dt : "20/12/2019" }, can be converted to a Date for sorting like this:

db.test.aggregate( [
{ 
  $project: { 
      dt: { 
         $dateFromString: { dateString: "$dt", format: "%d/%m/%Y" } 
      }
  }
},
] )

The result: { "_id" : 1, "dt" : ISODate("2019-12-20T00:00:00Z") }

And, the rest of the query can be an aggregation query with the same functionality as in the find query you are using now. The following code solves the issue.


Solution:

Your query:

documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending("ReceivedDate"));

translates to the following in aggregation in Mongo Shell:

db.test.aggregate( [
{ 
  $project: { 
      dt: { 
         $dateFromString: { dateString: "$dt", format: "%d/%m/%Y" } 
      }
  }
},
{ $sort: { dt : -1 } },
{ $skip: 2 },
{ $limit: 1 }
] )

And, in Java:

Bson addFields = addFields(new Field<Document>("dt", 
                                               new Document("$dateFromString", 
                                                            new Document("dateString", "$dt")
                                                                .append("format", "%d/%m/%Y")
                                                            )
));

List<Bson> pipeline = Arrays.asList(addFields, sort(descending("dt")), skip(2), limit(1));
List<Document> results = new ArrayList<>();
collection.aggregate(pipeline).into(results);

// The required MongoDB driver imports:
import org.bson.Document;
import org.bson.conversions.Bson;
import static com.mongodb.client.model.Aggregates.addFields;
import static com.mongodb.client.model.Aggregates.limit;
import static com.mongodb.client.model.Aggregates.skip;
import static com.mongodb.client.model.Aggregates.sort;
import static com.mongodb.client.model.Sorts.descending;
import com.mongodb.client.model.Field;


References:

  • Aggregation Optimization using $sort + $skip + $limit Sequence.
  • $expr usage.



回答2:


Managed to spend some time so thought I would share the fuller answer. This of course is only possible because of the help given for this question. Thanks everyone.

Using Robo 3T and a JavaScript style, I managed to work out the fuller answer I need.

db.getCollection('API_LOG').aggregate([
{ 
  $project: { 
      dt: { 
         $dateFromString: { dateString: "$ReceivedDate", format: "%d/%m/%Y" } 
      },
      ReceivedTime : 1,
      batch_id : 1,
      EventMessage : 1,
      ExpectedObservations:1,
      DataSetProvider:1,
      DataSetType:1,
      DataSetName:1,
  }
},
{ $sort: { dt : -1 } },
{ $skip: 0 },
{ $limit: 100 }
] )

Then The example java code from above worked really well for getting the List which I could then use to access relevant data.

Thanks for the help.



来源:https://stackoverflow.com/questions/59427200/mongo-java-get-all-documents-sort-string-date-as-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!