/******************************************************************************* * Copyright 2013 Open mHealth * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.openmhealth.reference.data.mongodb; import java.util.List; import org.mongojack.DBCursor; import org.mongojack.JacksonDBCollection; import org.openmhealth.reference.data.DataSet; import org.openmhealth.reference.domain.ColumnList; import org.openmhealth.reference.domain.Data; import org.openmhealth.reference.domain.MetaData; import org.openmhealth.reference.domain.MultiValueResult; import org.openmhealth.reference.domain.Schema; import org.openmhealth.reference.domain.mongodb.MongoData; import org.openmhealth.reference.domain.mongodb.MongoMultiValueResultCursor; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.QueryBuilder; /** * <p> * The interface to the database-backed set of data. * </p> * * @author John Jenkins */ public class MongoDataSet extends DataSet { /** * Default constructor. */ protected MongoDataSet() { // Get the collection to add indexes to. DBCollection collection = MongoDao.getInstance().getDb().getCollection(DB_NAME); // Ensure that there is an index on the token. collection .ensureIndex( new BasicDBObject(Data.JSON_KEY_OWNER, 1), DB_NAME + "_" + Data.JSON_KEY_OWNER + "_index", false); // Ensure that there is an index on the schema's ID. collection .ensureIndex( new BasicDBObject(Schema.JSON_KEY_ID, 1), DB_NAME + "_" + Schema.JSON_KEY_ID + "_index", false); // Ensure that there is an index on the schema's version. collection .ensureIndex( new BasicDBObject(Schema.JSON_KEY_VERSION, 1), DB_NAME + "_" + Schema.JSON_KEY_VERSION + "_index", false); // Build the index for sorting. String sortingFields = Data.JSON_KEY_METADATA + ColumnList.COLUMN_SEPARATOR + MetaData.JSON_KEY_TIMESTAMP; collection.ensureIndex( new BasicDBObject(sortingFields, 1), DB_NAME + "_" + sortingFields + "_index", false); } /* * (non-Javadoc) * @see org.openmhealth.reference.data.DataSet#setData(java.util.List) */ @Override public void storeData(final List<Data> data) { // Get the connection to the database. DB db = MongoDao.getInstance().getDb(); // Get the connection to the data with the Jackson wrapper. JacksonDBCollection<Data, Object> collection = JacksonDBCollection .wrap(db.getCollection(DB_NAME), Data.class); // Insert the data. collection.insert(data); } /* * (non-Javadoc) * @see org.openmhealth.reference.data.DataSet#getData(java.lang.String, java.lang.String, long, org.openmhealth.reference.domain.ColumnList, java.lang.Long, java.lang.Long) */ @Override public MultiValueResult<Data> getData( final String owner, final String schemaId, final long version, final ColumnList columnList, final long numToSkip, final long numToReturn) { // Get the connection to the database. DB db = MongoDao.getInstance().getDb(); // Get the connection to the data with the Jackson wrapper. JacksonDBCollection<MongoData, Object> collection = JacksonDBCollection .wrap(db.getCollection(DB_NAME), MongoData.class); // Build the query. QueryBuilder queryBuilder = QueryBuilder.start(); // Only select data for a single user. queryBuilder.and(Data.JSON_KEY_OWNER).is(owner); // Only select data for a given schema. queryBuilder.and(Schema.JSON_KEY_ID).is(schemaId); // Only select data for a given version of the the given schema. queryBuilder.and(Schema.JSON_KEY_VERSION).is(version); // Create the projection. DBObject projection = new BasicDBObject(); // Add the owner field. projection.put(Data.JSON_KEY_OWNER, 1); // Add the schema ID field. projection.put(Schema.JSON_KEY_ID, 1); // Add the schema version. projection.put(Schema.JSON_KEY_VERSION, 1); // Add the meta-data field. projection.put(Data.JSON_KEY_METADATA, 1); // Add all of the data or add only the specified columns if given. if(columnList.size() == 0) { projection.put(Data.JSON_KEY_DATA, 1); } else { if((columnList != null) && (columnList.size() > 0)) { for(String column : columnList.toList()) { projection .put( Data.JSON_KEY_DATA + ColumnList.COLUMN_SEPARATOR + column, 1); } } } // Build the query. DBCursor<MongoData> dbResult = collection.find(queryBuilder.get(), projection); // Build the sort field by sorting in reverse chronological order. DBObject sort = new BasicDBObject(); sort.put( Data.JSON_KEY_METADATA + ColumnList.COLUMN_SEPARATOR + MetaData.JSON_KEY_TIMESTAMP, -1); dbResult.sort(sort); // Page the results and return the multi-value result. return new MongoMultiValueResultCursor<Data>( dbResult .skip((new Long(numToSkip)).intValue()) .limit((new Long(numToReturn)).intValue())); } }