Displaying differences for changeset
 
display as  

src/java/m/timeseries/aggregate/V1_0.java

@@ -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();

src/java/m/timeseries/insert/V1_0.java

@@ -83,16 +83,17 @@
   }
 
   /**
-   *
+   * Add  
    * @param mongoUri
    * @param mongoCollection
-   * @param docId
-   * @param dataFile
-   * @param dataCol
-   * @param metadata
-   * @param dataFmt
-   * @param location
-   * @param LOG
+   * @param docId Mongo collection ID of the document with metadata about the location
+   * @param dataFile The CSV file to insert
+   * @param dataCol The particular column of data to insert if more than one is present.
+   *  leave null to insert all columns.
+   * @param metadata Additional information about the location
+   * @param dataFmt Date format of csv date column.
+   * @param location Point coordinates [longtitude, latitude]
+   * @param LOG optional logger
    * @throws FileNotFoundException
    * @throws IOException
    * @throws JSONException

src/java/utils/TimeseriesTable.java

@@ -30,8 +30,11 @@
  */
 public class TimeseriesTable {
 
+  // All timeseries data will be stored in a single document in the data array.
   public static String CHUNK_ALL = "CHUNK_ALL";
+  // Timeseries data will be broken up into documents representing a year of data.
   public static String CHUNK_YEAR = "CHUNK_YEAR";
+  // Data will be stored in individual documents.
   public static String CHUNK_NONE = "CHUNK_NONE";
 
   // Header is a list of strings (date, colname1, colname2...

test/service_tests/m/aggregate/big_data/service.properties

@@ -1,5 +1,6 @@
 # service endpoint, required
 url=http://localhost:8080/csip-timeseries/m/aggregate/1.0
+#url=http://csip.engr.colostate.edu:8087/csip-timeseries/m/aggregate/1.0
 
 # number of concurrent tests, optional, defaults to 1
 concurrency=1