{"action":"created","comment":{"url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/comments/47099924","id":47099924,"diff_hunk":"@@ -483,6 +482,121 @@ MongoDB.prototype.updateOrCreate = function updateOrCreate(model, data, options,\n };\n \n /**\n+ * Parses the data input for replace operations and returns the\n+ * sanitised version of the object.\n+ *\n+ * @param data\n+ * @returns {*}\n+ */\n+MongoDB.prototype.parseReplaceData = function(model, data, options) {\n+  options = options || {};\n+  var parsedData = {};\n+  \n+  var modelClass = this._models[model];\n+  \n+  var allowExtendedOperators = this.settings.allowExtendedOperators;\n+  if (options.hasOwnProperty('allowExtendedOperators')) {\n+      allowExtendedOperators = options.allowExtendedOperators === true;\n+  } else if (allowExtendedOperators !== false && modelClass.settings.mongodb\n+      && modelClass.settings.mongodb.hasOwnProperty('allowExtendedOperators')) {\n+      allowExtendedOperators = modelClass.settings.mongodb.allowExtendedOperators === true;\n+  } else if (allowExtendedOperators === true) {\n+      allowExtendedOperators = true;\n+  }\n+  \n+  if (allowExtendedOperators) {\n+    // Check for other operators and sanitize the data obj\n+    var acceptedOperators = [\n+      // Field operators\n+      '$currentDate', '$inc', '$max', '$min', '$mul', '$rename', '$setOnInsert', '$set', '$unset',\n+      // Array operators\n+      '$addToSet', '$pop', '$pullAll', '$pull', '$pushAll', '$push',\n+      // Bitwise operator\n+      '$bit'\n+    ];\n+\n+    var usedOperators = 0;\n+\n+    // each accepted operator will take its place on parsedData if defined\n+    for (var i = 0; i < acceptedOperators.length; i++) {\n+      if(data[acceptedOperators[i]]) {\n+        parsedData[acceptedOperators[i]] = data[acceptedOperators[i]];\n+        usedOperators++;\n+      }\n+    }\n+\n+    // if parsedData is still empty, then we fallback to $set operator\n+    if(usedOperators === 0) {\n+      parsedData.$set = data;\n+    }\n+  } else {\n+    parsedData.$set = data;\n+  }\n+  \n+  parsedData.$unset = {};\n+  var props = this.getModelDefinition(model).properties;\n+  var keys = Object.keys(props);\n+  for (var i = 0, n = keys.length; i < n; i++) {\n+    var key = keys[i];\n+    var p = parsedData.$set[key];\n+    if (key != 'id' && p == null) {\n+      parsedData.$unset[key] = \"\";\n+    }\n+  }\n+  return parsedData;","path":"lib/mongodb.js","position":73,"original_position":73,"commit_id":"516aff8944da2fc81f03c939cb9b53022404d7f8","original_commit_id":"516aff8944da2fc81f03c939cb9b53022404d7f8","user":{"login":"bajtos","id":1140553,"avatar_url":"https://avatars.githubusercontent.com/u/1140553?v=3","gravatar_id":"","url":"https://api.github.com/users/bajtos","html_url":"https://github.com/bajtos","followers_url":"https://api.github.com/users/bajtos/followers","following_url":"https://api.github.com/users/bajtos/following{/other_user}","gists_url":"https://api.github.com/users/bajtos/gists{/gist_id}","starred_url":"https://api.github.com/users/bajtos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bajtos/subscriptions","organizations_url":"https://api.github.com/users/bajtos/orgs","repos_url":"https://api.github.com/users/bajtos/repos","events_url":"https://api.github.com/users/bajtos/events{/privacy}","received_events_url":"https://api.github.com/users/bajtos/received_events","type":"User","site_admin":false},"body":"I think the solution based on `{ $set, $unset }` will not work correctly when the data contains any extra properties not defined in the model. I believe we need to use [Replace the document](https://docs.mongodb.org/manual/tutorial/modify-documents/#replace-the-document) variant instead.\r\n\r\n> To replace the entire content of a document except for the _id field, pass an entirely new document as the second argument to update().","created_at":"2015-12-09T14:56:06Z","updated_at":"2015-12-09T14:56:06Z","html_url":"https://github.com/strongloop/loopback-connector-mongodb/pull/202#discussion_r47099924","pull_request_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202","_links":{"self":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/comments/47099924"},"html":{"href":"https://github.com/strongloop/loopback-connector-mongodb/pull/202#discussion_r47099924"},"pull_request":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202"}}},"pull_request":{"url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202","id":53045357,"html_url":"https://github.com/strongloop/loopback-connector-mongodb/pull/202","diff_url":"https://github.com/strongloop/loopback-connector-mongodb/pull/202.diff","patch_url":"https://github.com/strongloop/loopback-connector-mongodb/pull/202.patch","issue_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/202","number":202,"state":"open","locked":false,"title":"WIP: Initial implementation for replace - mongodb","user":{"login":"Amir-61","id":10672146,"avatar_url":"https://avatars.githubusercontent.com/u/10672146?v=3","gravatar_id":"","url":"https://api.github.com/users/Amir-61","html_url":"https://github.com/Amir-61","followers_url":"https://api.github.com/users/Amir-61/followers","following_url":"https://api.github.com/users/Amir-61/following{/other_user}","gists_url":"https://api.github.com/users/Amir-61/gists{/gist_id}","starred_url":"https://api.github.com/users/Amir-61/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Amir-61/subscriptions","organizations_url":"https://api.github.com/users/Amir-61/orgs","repos_url":"https://api.github.com/users/Amir-61/repos","events_url":"https://api.github.com/users/Amir-61/events{/privacy}","received_events_url":"https://api.github.com/users/Amir-61/received_events","type":"User","site_admin":false},"body":"Hi @bajtos,\r\n\r\nPlease note this is just in progress implementation (Very initial implementation); just to make sure I'm on the right track.\r\n##### Added functionality:\r\n\r\n*Initial implementation for replaceAttribute\r\n*Initial implementation for replaceOrCreate\r\n\r\n##### Other notes:\r\n\r\n* These changes are related to the changes in the pull requests under `loopback-connector` and `loopback-datasource-juggler`\r\n* It seems test cases cannot be run on windows machines; I need to dig into it.\r\n\r\n","created_at":"2015-12-08T22:01:57Z","updated_at":"2015-12-09T14:56:06Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9e4feafc561ad45f1f7596a00b970ca5b9e8b8aa","assignee":{"login":"bajtos","id":1140553,"avatar_url":"https://avatars.githubusercontent.com/u/1140553?v=3","gravatar_id":"","url":"https://api.github.com/users/bajtos","html_url":"https://github.com/bajtos","followers_url":"https://api.github.com/users/bajtos/followers","following_url":"https://api.github.com/users/bajtos/following{/other_user}","gists_url":"https://api.github.com/users/bajtos/gists{/gist_id}","starred_url":"https://api.github.com/users/bajtos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bajtos/subscriptions","organizations_url":"https://api.github.com/users/bajtos/orgs","repos_url":"https://api.github.com/users/bajtos/repos","events_url":"https://api.github.com/users/bajtos/events{/privacy}","received_events_url":"https://api.github.com/users/bajtos/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202/commits","review_comments_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202/comments","review_comment_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/comments{/number}","comments_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/202/comments","statuses_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/statuses/516aff8944da2fc81f03c939cb9b53022404d7f8","head":{"label":"strongloop:replace","ref":"replace","sha":"516aff8944da2fc81f03c939cb9b53022404d7f8","user":{"login":"strongloop","id":3020012,"avatar_url":"https://avatars.githubusercontent.com/u/3020012?v=3","gravatar_id":"","url":"https://api.github.com/users/strongloop","html_url":"https://github.com/strongloop","followers_url":"https://api.github.com/users/strongloop/followers","following_url":"https://api.github.com/users/strongloop/following{/other_user}","gists_url":"https://api.github.com/users/strongloop/gists{/gist_id}","starred_url":"https://api.github.com/users/strongloop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongloop/subscriptions","organizations_url":"https://api.github.com/users/strongloop/orgs","repos_url":"https://api.github.com/users/strongloop/repos","events_url":"https://api.github.com/users/strongloop/events{/privacy}","received_events_url":"https://api.github.com/users/strongloop/received_events","type":"Organization","site_admin":false},"repo":{"id":10975056,"name":"loopback-connector-mongodb","full_name":"strongloop/loopback-connector-mongodb","owner":{"login":"strongloop","id":3020012,"avatar_url":"https://avatars.githubusercontent.com/u/3020012?v=3","gravatar_id":"","url":"https://api.github.com/users/strongloop","html_url":"https://github.com/strongloop","followers_url":"https://api.github.com/users/strongloop/followers","following_url":"https://api.github.com/users/strongloop/following{/other_user}","gists_url":"https://api.github.com/users/strongloop/gists{/gist_id}","starred_url":"https://api.github.com/users/strongloop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongloop/subscriptions","organizations_url":"https://api.github.com/users/strongloop/orgs","repos_url":"https://api.github.com/users/strongloop/repos","events_url":"https://api.github.com/users/strongloop/events{/privacy}","received_events_url":"https://api.github.com/users/strongloop/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/strongloop/loopback-connector-mongodb","description":"The official MongoDB connector for the LoopBack framework.","fork":false,"url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb","forks_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/forks","keys_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/teams","hooks_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/hooks","issue_events_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/events{/number}","events_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/events","assignees_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/assignees{/user}","branches_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/branches{/branch}","tags_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/tags","blobs_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/statuses/{sha}","languages_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/languages","stargazers_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/stargazers","contributors_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/contributors","subscribers_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/subscribers","subscription_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/subscription","commits_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/contents/{+path}","compare_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/merges","archive_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/downloads","issues_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues{/number}","pulls_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls{/number}","milestones_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/milestones{/number}","notifications_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/labels{/name}","releases_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/releases{/id}","created_at":"2013-06-26T18:04:58Z","updated_at":"2015-12-09T09:15:06Z","pushed_at":"2015-12-08T22:01:57Z","git_url":"git://github.com/strongloop/loopback-connector-mongodb.git","ssh_url":"git@github.com:strongloop/loopback-connector-mongodb.git","clone_url":"https://github.com/strongloop/loopback-connector-mongodb.git","svn_url":"https://github.com/strongloop/loopback-connector-mongodb","homepage":"https://docs.strongloop.com/display/public/LB/MongoDB+connector","size":2016,"stargazers_count":61,"watchers_count":61,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":66,"mirror_url":null,"open_issues_count":70,"forks":66,"open_issues":70,"watchers":61,"default_branch":"master"}},"base":{"label":"strongloop:master","ref":"master","sha":"f1815d7286be60460ff3aa523a2205f693ea1d47","user":{"login":"strongloop","id":3020012,"avatar_url":"https://avatars.githubusercontent.com/u/3020012?v=3","gravatar_id":"","url":"https://api.github.com/users/strongloop","html_url":"https://github.com/strongloop","followers_url":"https://api.github.com/users/strongloop/followers","following_url":"https://api.github.com/users/strongloop/following{/other_user}","gists_url":"https://api.github.com/users/strongloop/gists{/gist_id}","starred_url":"https://api.github.com/users/strongloop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongloop/subscriptions","organizations_url":"https://api.github.com/users/strongloop/orgs","repos_url":"https://api.github.com/users/strongloop/repos","events_url":"https://api.github.com/users/strongloop/events{/privacy}","received_events_url":"https://api.github.com/users/strongloop/received_events","type":"Organization","site_admin":false},"repo":{"id":10975056,"name":"loopback-connector-mongodb","full_name":"strongloop/loopback-connector-mongodb","owner":{"login":"strongloop","id":3020012,"avatar_url":"https://avatars.githubusercontent.com/u/3020012?v=3","gravatar_id":"","url":"https://api.github.com/users/strongloop","html_url":"https://github.com/strongloop","followers_url":"https://api.github.com/users/strongloop/followers","following_url":"https://api.github.com/users/strongloop/following{/other_user}","gists_url":"https://api.github.com/users/strongloop/gists{/gist_id}","starred_url":"https://api.github.com/users/strongloop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongloop/subscriptions","organizations_url":"https://api.github.com/users/strongloop/orgs","repos_url":"https://api.github.com/users/strongloop/repos","events_url":"https://api.github.com/users/strongloop/events{/privacy}","received_events_url":"https://api.github.com/users/strongloop/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/strongloop/loopback-connector-mongodb","description":"The official MongoDB connector for the LoopBack framework.","fork":false,"url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb","forks_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/forks","keys_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/teams","hooks_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/hooks","issue_events_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/events{/number}","events_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/events","assignees_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/assignees{/user}","branches_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/branches{/branch}","tags_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/tags","blobs_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/statuses/{sha}","languages_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/languages","stargazers_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/stargazers","contributors_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/contributors","subscribers_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/subscribers","subscription_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/subscription","commits_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/contents/{+path}","compare_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/merges","archive_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/downloads","issues_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues{/number}","pulls_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls{/number}","milestones_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/milestones{/number}","notifications_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/labels{/name}","releases_url":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/releases{/id}","created_at":"2013-06-26T18:04:58Z","updated_at":"2015-12-09T09:15:06Z","pushed_at":"2015-12-08T22:01:57Z","git_url":"git://github.com/strongloop/loopback-connector-mongodb.git","ssh_url":"git@github.com:strongloop/loopback-connector-mongodb.git","clone_url":"https://github.com/strongloop/loopback-connector-mongodb.git","svn_url":"https://github.com/strongloop/loopback-connector-mongodb","homepage":"https://docs.strongloop.com/display/public/LB/MongoDB+connector","size":2016,"stargazers_count":61,"watchers_count":61,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":66,"mirror_url":null,"open_issues_count":70,"forks":66,"open_issues":70,"watchers":61,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202"},"html":{"href":"https://github.com/strongloop/loopback-connector-mongodb/pull/202"},"issue":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/202"},"comments":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/issues/202/comments"},"review_comments":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202/comments"},"review_comment":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/pulls/202/commits"},"statuses":{"href":"https://api.github.com/repos/strongloop/loopback-connector-mongodb/statuses/516aff8944da2fc81f03c939cb9b53022404d7f8"}}}}