@@ -11,7 +11,11 @@ |
import com.mongodb.client.FindIterable; |
import com.mongodb.client.MongoCollection; |
import com.mongodb.client.MongoDatabase; |
-import com.mongodb.client.model.Aggregates; |
+import static com.mongodb.client.model.Aggregates.group; |
+import static com.mongodb.client.model.Aggregates.match; |
+import static com.mongodb.client.model.Aggregates.project; |
+import static com.mongodb.client.model.Aggregates.sort; |
+import static com.mongodb.client.model.Aggregates.unwind; |
import com.mongodb.client.model.Filters; |
import javax.ws.rs.Path; |
import csip.ModelDataService; |
@@ -22,7 +26,7 @@ |
import java.text.ParseException; |
import java.text.SimpleDateFormat; |
import java.util.ArrayList; |
-import java.util.Arrays; |
+import static java.util.Arrays.asList; |
import java.util.Date; |
import java.util.List; |
import java.util.TimeZone; |
@@ -81,6 +85,18 @@ |
putResult("result", results); |
} |
|
+ /** |
+ * |
+ * @param mongoUri |
+ * @param mongoCollection |
+ * @param searchFeature |
+ * @param searchId |
+ * @param startDateStr |
+ * @param endDateStr |
+ * @param aggregationLevel |
+ * @throws JSONException |
+ * @throws ServiceException |
+ */ |
void run(String mongoUri, String mongoCollection, JSONObject searchFeature, String searchId, |
String startDateStr, String endDateStr, String aggregationLevel) |
throws JSONException, ServiceException { |
@@ -101,6 +117,8 @@ |
} |
} |
|
+ // This will find all location (top-level) documents by checking that the |
+ // foreign-key location_id does not exist. |
Document locationsOnly = new Document().append("location_id", new Document().append("$exists", false)); |
if (searchFeature == null) { |
FindIterable<Document> c; |
@@ -145,53 +163,39 @@ |
|
private JSONObject getResult(MongoCollection<Document> c, Document locationDoc, Date startDate, Date endDate, |
String aggregationLevel) throws JSONException { |
- String dateFormat = (String) locationDoc.get("date_fmt"); |
- if (dateFormat == null) { |
- dateFormat = "yyyy-MM-dd"; |
- } |
- SimpleDateFormat ft = new SimpleDateFormat(dateFormat); |
- ft.setTimeZone(TimeZone.getTimeZone("UTC")); |
- |
+ /* |
+ db.getCollection("bigdata test series").aggregate([ |
+ { "$match": { "location_id": "big_yearlychunks" } }, |
+ { "$unwind": "$data" }, |
+ { "$project": { |
+ "tmin": { "$arrayElemAt": ["$data", 1] }, |
+ "month": { $month: { "$arrayElemAt": ["$data", 0] } }, |
+ "year": { $year: { "$arrayElemAt": ["$data", 0] } }, |
+ } }, |
+ { "$group": { |
+ "_id": { month: "$month", year: "$year" }, |
+ "tmin_avg": { "$avg": "$tmin" }, |
+ "tmin_min": { "$min": "$tmin" }, |
+ "tmin_max": { "$max": "$tmin" }, |
+ "month": { "$first": "$month" }, |
+ "year": { "$first": "$year" }, |
+ } }, |
+ { "$sort": { "year": 1, "month": 1 } }, |
+ ]) |
+ */ |
List<String> header = (ArrayList) locationDoc.get("header"); |
- List<List<Object>> data = (ArrayList) locationDoc.get("data"); |
List<List<Object>> filtered = new ArrayList(); |
|
- Document datesQuery = new Document(); |
- if ((startDate != null || endDate != null)) { |
- datesQuery = new Document(); |
- if (startDate != null) { |
- datesQuery.append("$gte", startDate); |
- } |
- if (endDate != null) { |
- datesQuery.append("$lte", endDate); |
- } |
- datesQuery = new Document("data.0", datesQuery); |
- } |
- |
- Document project = new Document(); |
- for (int i = 1; i < header.size(); i++) { |
- project.append(header.get(i), new Document("$arrayElemAt", Arrays.asList("$data", i))); |
- } |
- project.append("month", new Document("$month", new Document("$arrayElemAt", Arrays.asList("$data", 0)))); |
- project.append("year", new Document("$year", new Document("$arrayElemAt", Arrays.asList("$data", 0)))); |
- |
- Document group = new Document("_id", new Document("month", "$month").append("year", "$year")); |
- for (int i = 1; i < header.size(); i++) { |
- group.append(header.get(i) + "_avg", new Document("$avg", "$" + header.get(i))); |
- } |
- group.append("month", new Document("$first", "$month")); |
- group.append("year", new Document("$first", "$year")); |
- |
- // Export for robomongo |
- List<Bson> aggList = Arrays.asList( |
- Aggregates.match(new Document("location_id", locationDoc.getString("_id"))), |
- Aggregates.unwind("$data"), |
- Aggregates.match(datesQuery), |
- Aggregates.project(project), |
- new Document("$group", group), |
- new Document("$sort", new Document("year", 1).append("month", 1)) |
+ List<Bson> aggList = asList( |
+ match(new Document("location_id", locationDoc.getString("_id"))), |
+ unwind("$data"), |
+ match(new Document("data.0", filterData(startDate, endDate))), |
+ project(projectData(header)), |
+ // I can't use Aggregates.group because $first in the _id field causes an error. |
+ new Document("$group", groupData(header)), |
+ sort(new Document("year", 1).append("month", 1)) |
); |
- |
+ |
AggregateIterable<Document> iter = c.aggregate(aggList).allowDiskUse(true); |
for (Document d : iter) { |
List<Object> row = new ArrayList<>(); |
@@ -204,20 +208,45 @@ |
filtered.add(row); |
} |
|
- JSONObject res = new JSONObject(); |
- res.put("_id", locationDoc.get("_id")); |
- Document location = (Document) locationDoc.get("location"); |
- if (location != null) { |
- List<Double> coords = (List<Double>) location.get("coordinates"); |
- res.put("location", coords); |
- } |
+ JSONObject res = new JSONObject(locationDoc.toJson()); |
res.put("header", header); |
res.put("data", filtered); |
- Document metadata = (Document) locationDoc.get("metadata"); |
- res.put("metadata", new JSONObject(metadata.toJson())); |
|
return res; |
} |
+ |
+ private Document filterData(Date startDate, Date endDate) { |
+ Document datesQuery = new Document(); |
+ if ((startDate != null || endDate != null)) { |
+ if (startDate != null) { |
+ datesQuery.append("$gte", startDate); |
+ } |
+ if (endDate != null) { |
+ datesQuery.append("$lte", endDate); |
+ } |
+ } |
+ return datesQuery; |
+ } |
+ |
+ private Document projectData(List<String> header) { |
+ Document project = new Document(); |
+ for (int i = 1; i < header.size(); i++) { |
+ project.append(header.get(i), new Document("$arrayElemAt", asList("$data", i))); |
+ } |
+ project.append("month", new Document("$month", new Document("$arrayElemAt", asList("$data", 0)))); |
+ project.append("year", new Document("$year", new Document("$arrayElemAt", asList("$data", 0)))); |
+ return project; |
+ } |
+ |
+ private Document groupData(List<String> header) { |
+ Document group = new Document("_id", new Document("month", "$month").append("year", "$year")); |
+ for (int i = 1; i < header.size(); i++) { |
+ group.append(header.get(i) + "_avg", new Document("$avg", "$" + header.get(i))); |
+ } |
+ group.append("month", new Document("$first", "$month")); |
+ group.append("year", new Document("$first", "$year")); |
+ return group; |
+ } |
|
public List<Bson> getMatch(JSONObject feat, String search_id) throws JSONException, IOException { |
String geom = feat.getJSONObject("geometry").toString(); |