diff --git a/lib/datastore.js b/lib/datastore.js
index 76d74ebe..c567f39c 100755
--- a/lib/datastore.js
+++ b/lib/datastore.js
@@ -577,7 +577,6 @@ class Datastore extends EventEmitter {
         const callback = cb || function () {};
         const multi = options.multi !== undefined ? options.multi : false;
         const upsert = options.upsert !== undefined ? options.upsert : false;
-        const position = options.position !== undefined ? options.position : false;
 
         async.waterfall([
             cb => {
@@ -604,7 +603,7 @@ class Datastore extends EventEmitter {
                         // updateQuery contains modifiers, use the find query as the base,
                         // strip it from all operators and update it according to updateQuery
                         try {
-                            toBeInserted = model.modify(model.deepCopy(query, true), updateQuery, position);
+                            toBeInserted = model.modify(model.deepCopy(query, true), updateQuery, options);
                         } catch (err) {
                             return callback(err);
                         }
@@ -640,10 +639,9 @@ class Datastore extends EventEmitter {
                                 if (this.timestampData) {
                                     createdAt = candidates[i].createdAt;
                                 }
-                                const modifiedDoc = model.modify(candidates[i], updateQuery, position);
+                                const modifiedDoc = model.modify(candidates[i], updateQuery, options);
                                 if (this.timestampData) {
                                     modifiedDoc.createdAt = createdAt;
-                                    // modifiedDoc.updatedAt = new Date();
                                     if (updateQuery.$set.updatedAt === undefined) {
                                         modifiedDoc.updatedAt = new Date();
                                     }
diff --git a/lib/model.js b/lib/model.js
index ab06606c..acf4674a 100755
--- a/lib/model.js
+++ b/lib/model.js
@@ -647,11 +647,12 @@ lastStepModifierFunctions.$min = function (obj, field, value) {
 
 // Given its name, create the complete modifier function
 function createModifierFunction (modifier) {
-    return function (obj, field, value, position) {
-        let fieldParts = typeof field === 'string' ? field.split('.') : field;
+    return function (obj, field, value, options) {
+        const fieldParts = typeof field === 'string' ? field.split('.') : field;
 
         if (fieldParts.length === 1) {
-            lastStepModifierFunctions[modifier](obj, field, value, position);
+            lastStepModifierFunctions[modifier](obj, field, value, options);
+
         } else {
             if (obj[fieldParts[0]] === undefined) {
                 // Bad looking specific fix, needs to be generalized modifiers that behave like $unset are implemented
@@ -660,7 +661,28 @@ function createModifierFunction (modifier) {
                 }
                 obj[fieldParts[0]] = {};
             }
-            modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value, position);
+
+            if (fieldParts[1] === '$') {
+                const arrayKey = fieldParts[0];
+                const arrayObj = obj[arrayKey];
+                const query = options.query;
+
+                if (!Array.isArray) {
+                    throw new Error("You cannot apply the positional ($) operator to a non-array field");
+                }
+
+                for (let i = arrayObj.length - 1; i >= 0; i -= 1) {
+                    obj[arrayKey] = arrayObj[i];
+
+                    if (match(obj, query)) {
+                        obj[arrayKey] = arrayObj;
+                        fieldParts[1] = i;
+                        break;
+                    }
+                }
+            }
+
+            modifierFunctions[modifier](obj[fieldParts[0]], fieldParts.slice(1), value, options);
         }
     };
 }
@@ -671,7 +693,11 @@ Object.keys(lastStepModifierFunctions).forEach(function (modifier) {
 });
 
 /** Modify a DB object according to an update query */
-function modify (obj, updateQuery, position) {
+function modify (obj, updateQuery, options = {}) {
+    const position = options.position;
+    const query = options.query;
+
+
     let keys = Object.keys(updateQuery),
         firstChars = keys.map(item => item[0]),
         dollarFirstChars = firstChars.filter(item => item === '$'),
@@ -690,6 +716,7 @@ function modify (obj, updateQuery, position) {
         // Simply replace the object with the update query contents
         newDoc = deepCopy(updateQuery);
         newDoc._id = obj._id;
+
     } else {
         // Apply modifiers
         modifiers = [...keys];
@@ -706,8 +733,32 @@ function modify (obj, updateQuery, position) {
             }
 
             const keys = Object.keys(updateQuery[m]);
-            keys.forEach(function (k) {
-                modifierFunctions[m](newDoc, k, updateQuery[m][k], position);
+            keys.forEach(k => {
+                let queryFields = k.split('.');
+                let index = queryFields.indexOf('$');
+
+                if (index === -1) {
+                    const arrayField = queryFields[index - 1];
+                    const queryKeys = Object.keys(query);
+
+                    let i = queryKeys.length,
+                        found = false;
+
+                    while (i--) {
+                        let fields = queryKeys[i].split('.');
+
+                        if (fields.indexOf(arrayField) !== -1) {
+                            found = true;
+                            break;
+                        }
+                    }
+
+                    if (!found) {
+                        throw new Error("You must include the relevant array field in query when using the positional ($) operator");
+                    }
+                }
+
+                modifierFunctions[m](newDoc, k, updateQuery[m][k], options);
             });
         });
     }