function (baseCollection, tempCollection) { -- Supply two collections as input one is basecoll and another one is tempcoll db.getCollection(baseCollection).mapReduce( -- db.getCollection(baseCollection) function () { if (!this.UserId) this.UserId = 0; key = { 'VersionId': this.VersionId, 'UserId': this.UserId, 'VA': this.VA }; emit(key, { "CompanyId": this.CompanyId, "ScoreSum": this.Score, "ReviewScoreSum": this.ReviewScore, "Count": 1, "ScoreCount": 0, "ReviewScoreCount": 0, "Sites": [] }); for (var i = 0; i < this.Sites.length; i++) { emit( key, { "CompanyId": this.CompanyId, "ScoreSum": 0, "ReviewScoreSum": 0, "Count": 0, "ScoreCount": 0, "ReviewScoreCount": 0, "Sites": [{ "Name": this.Sites[i].Name, "Count": 1, "ReviewScoreCount": this.Sites[i].ReviewScore > 0 ? 1 : 0, "ReviewCount": this.Sites[i].ReviewCount, "ScoreSum": this.Sites[i].Score, "ReviewScoreSum": this.Sites[i].ReviewScore > 0 ? this.Sites[i].ReviewScore : 0, "BusinessNameScoreSum": this.Sites[i].BusinessName.Score, "PhoneScoreSum": this.Sites[i].Phone.Score, "WebSiteScoreSum": this.Sites[i].WebSite.Score, "AddressScoreSum": this.Sites[i].Address.Score, "CityScoreSum": this.Sites[i].City.Score, "StateScoreSum": this.Sites[i].State.Score, "PostalCodeScoreSum": this.Sites[i].PostalCode.Score, "FaxScoreSum": this.Sites[i].Fax.Score, // Profile Completeness Fields "BusinessNameExists": this.Sites[i].BusinessName.Exists * 1, // bool -> int "PhoneExists": this.Sites[i].Phone.Exists * 1, "WebSiteExists": this.Sites[i].WebSite.Exists * 1, "AddressExists": this.Sites[i].Address.Exists * 1, "PhotosExists": this.Sites[i].Photos.Exists * 1, "CategoriesExists": this.Sites[i].Categories.Exists * 1, "HoursOfOperationExists": this.Sites[i].HoursOfOperation.Exists * 1, "DescriptionExists": this.Sites[i].Description.Exists * 1 }] }); } }, function (mapKey, mapValues) { var reducedDocument = { Count: 0 }; var dict = {}; var extractRule = {}; var rules = internal_rule(); var totalReviewScore = 0.0; var totalScore = 0.0; var totalScoreCount = 0; var totalReviewScoreCount = 0; for (var i = 0; i < mapValues.length; i++) { reducedDocument.Count += mapValues[i].Count; reducedDocument.CompanyId = mapValues[i].CompanyId; for (var j = 0; j < mapValues[i].Sites.length; j++) { if (!dict[mapValues[i].Sites[j].Name]) { dict[mapValues[i].Sites[j].Name] = { Name: mapValues[i].Sites[j].Name, Count: 0, ReviewScoreCount: 0, ReviewCount: 0, ScoreSum: 0, ReviewScoreSum: 0, BusinessNameScoreSum: 0, PhoneScoreSum: 0, WebSiteScoreSum: 0, AddressScoreSum: 0, CityScoreSum: 0, StateScoreSum: 0, PostalCodeScoreSum: 0, FaxScoreSum: 0, BusinessNameExists: 0, PhoneExists: 0, WebSiteExists: 0, AddressExists: 0, PhotosExists: 0, CategoriesExists: 0, HoursOfOperationExists: 0, DescriptionExists: 0 }; } dict[mapValues[i].Sites[j].Name].ScoreSum += mapValues[i].Sites[j].ScoreSum; totalScore += mapValues[i].Sites[j].ScoreSum; totalScoreCount += mapValues[i].Sites[j].Count; var length = internal_site_exists(mapValues[i].Sites[j].Name, rules); if (length == -1) { dict[mapValues[i].Sites[j].Name].BusinessNameScoreSum += mapValues[i].Sites[j].BusinessNameScoreSum; dict[mapValues[i].Sites[j].Name].PhoneScoreSum += mapValues[i].Sites[j].PhoneScoreSum; dict[mapValues[i].Sites[j].Name].WebSiteScoreSum += mapValues[i].Sites[j].WebSiteScoreSum; dict[mapValues[i].Sites[j].Name].AddressScoreSum += mapValues[i].Sites[j].AddressScoreSum; dict[mapValues[i].Sites[j].Name].CityScoreSum += mapValues[i].Sites[j].CityScoreSum; dict[mapValues[i].Sites[j].Name].StateScoreSum += mapValues[i].Sites[j].StateScoreSum; dict[mapValues[i].Sites[j].Name].PostalCodeScoreSum += mapValues[i].Sites[j].PostalCodeScoreSum; dict[mapValues[i].Sites[j].Name].FaxScoreSum += mapValues[i].Sites[j].FaxScoreSum; dict[mapValues[i].Sites[j].Name].BusinessNameExists += mapValues[i].Sites[j].BusinessNameExists; dict[mapValues[i].Sites[j].Name].PhoneExists += mapValues[i].Sites[j].PhoneExists; dict[mapValues[i].Sites[j].Name].WebSiteExists += mapValues[i].Sites[j].WebSiteExists; dict[mapValues[i].Sites[j].Name].AddressExists += mapValues[i].Sites[j].AddressExists; dict[mapValues[i].Sites[j].Name].PhotosExists += mapValues[i].Sites[j].PhotosExists; dict[mapValues[i].Sites[j].Name].CategoriesExists += mapValues[i].Sites[j].CategoriesExists; dict[mapValues[i].Sites[j].Name].HoursOfOperationExists += mapValues[i].Sites[j].HoursOfOperationExists; dict[mapValues[i].Sites[j].Name].DescriptionExists += mapValues[i].Sites[j].DescriptionExists; } else { if (!(internal_exists("BusinessName", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].BusinessNameScoreSum += mapValues[i].Sites[j].BusinessNameScoreSum; dict[mapValues[i].Sites[j].Name].BusinessNameExists += mapValues[i].Sites[j].BusinessNameExists; } if (!(internal_exists("Phone", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].PhoneScoreSum += mapValues[i].Sites[j].PhoneScoreSum; dict[mapValues[i].Sites[j].Name].PhoneExists += mapValues[i].Sites[j].PhoneExists; } if (!(internal_exists("WebSite", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].WebSiteScoreSum += mapValues[i].Sites[j].WebSiteScoreSum; dict[mapValues[i].Sites[j].Name].WebSiteExists += mapValues[i].Sites[j].WebSiteExists; } if (!(internal_exists("Address", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].AddressScoreSum += mapValues[i].Sites[j].AddressScoreSum; dict[mapValues[i].Sites[j].Name].AddressExists += mapValues[i].Sites[j].AddressExists; } if (!(internal_exists("City", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].CityScoreSum += mapValues[i].Sites[j].CityScoreSum; } if (!(internal_exists("State", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].StateScoreSum += mapValues[i].Sites[j].StateScoreSum; } if (!(internal_exists("PostalCode", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].PostalCodeScoreSum += mapValues[i].Sites[j].PostalCodeScoreSum; } if (!(internal_exists("Fax", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].FaxScoreSum += mapValues[i].Sites[j].FaxScoreSum; } if (!(internal_exists("Photos", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].PhotosExists += mapValues[i].Sites[j].PhotosExists; } if (!(internal_exists("Categories", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].CategoriesExists += mapValues[i].Sites[j].CategoriesExists; } if (!(internal_exists("HoursOfOperation", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].HoursOfOperationExists += mapValues[i].Sites[j].HoursOfOperationExists; } if (!(internal_exists("Description", rules[length].Fields))) { dict[mapValues[i].Sites[j].Name].DescriptionExists += mapValues[i].Sites[j].DescriptionExists; } } dict[mapValues[i].Sites[j].Name].ReviewScoreSum += mapValues[i].Sites[j].ReviewScoreSum; totalReviewScore += mapValues[i].Sites[j].ReviewScoreSum; totalReviewScoreCount += mapValues[i].Sites[j].ReviewScoreCount; dict[mapValues[i].Sites[j].Name].ReviewCount += mapValues[i].Sites[j].ReviewCount; dict[mapValues[i].Sites[j].Name].Count += mapValues[i].Sites[j].Count; dict[mapValues[i].Sites[j].Name].ReviewScoreCount += mapValues[i].Sites[j].ReviewScoreCount; } } reducedDocument.ReviewScoreSum = totalReviewScoreCount == 0 ? 0 : totalReviewScore; reducedDocument.ScoreSum = totalScore; reducedDocument.ScoreCount = totalScoreCount; reducedDocument.ReviewScoreCount = totalReviewScoreCount; reducedDocument.Sites = []; for (var field in dict) reducedDocument.Sites.push(dict[field]); return reducedDocument; }, { out: tempCollection, finalize: function (mapKey, reducedValue) { var rules = internal_rule(); modifiedDocument = mapKey; modifiedDocument.CompanyId = reducedValue.CompanyId; modifiedDocument.Count = reducedValue.Count; modifiedDocument.Score = reducedValue.ScoreCount == 0 ? 0 : reducedValue.ScoreSum / reducedValue.ScoreCount; modifiedDocument.ReviewScore = reducedValue.ReviewScoreCount == 0 ? -1 : reducedValue.ReviewScoreSum / reducedValue.ReviewScoreCount; modifiedDocument.ScoreCount = reducedValue.ScoreCount; modifiedDocument.ReviewScoreCount = reducedValue.ReviewScoreCount; modifiedDocument.Sites = []; for (var i = 0; i < reducedValue.Sites.length; i++) { var currentSite = {}; currentSite.Name = reducedValue.Sites[i].Name; currentSite.Score = reducedValue.Sites[i].ScoreSum / reducedValue.Sites[i].Count; currentSite.ReviewScore = reducedValue.Sites[i].ReviewScoreCount == 0 ? -1 : reducedValue.Sites[i].ReviewScoreSum / reducedValue.Sites[i].ReviewScoreCount; currentSite.BusinessNameScore = reducedValue.Sites[i].BusinessNameScoreSum / reducedValue.Sites[i].Count; currentSite.PhoneScore = reducedValue.Sites[i].PhoneScoreSum / reducedValue.Sites[i].Count; currentSite.WebSiteScore = reducedValue.Sites[i].WebSiteScoreSum / reducedValue.Sites[i].Count; currentSite.AddressScore = reducedValue.Sites[i].AddressScoreSum / reducedValue.Sites[i].Count; currentSite.CityScore = reducedValue.Sites[i].CityScoreSum / reducedValue.Sites[i].Count; currentSite.StateScore = reducedValue.Sites[i].StateScoreSum / reducedValue.Sites[i].Count; currentSite.PostalCodeScore = reducedValue.Sites[i].PostalCodeScoreSum / reducedValue.Sites[i].Count; currentSite.FaxScore = reducedValue.Sites[i].FaxScoreSum / reducedValue.Sites[i].Count; currentSite.ReviewCount = reducedValue.Sites[i].ReviewCount; currentSite.Count = reducedValue.Sites[i].Count; currentSite.ReviewScoreCount = reducedValue.Sites[i].ReviewScoreCount; currentSite.BusinessNameExists = (reducedValue.Sites[i].BusinessNameExists / reducedValue.Sites[i].Count) * 100; currentSite.PhoneExists = (reducedValue.Sites[i].PhoneExists / reducedValue.Sites[i].Count) * 100; currentSite.WebSiteExists = (reducedValue.Sites[i].WebSiteExists / reducedValue.Sites[i].Count) * 100; currentSite.AddressExists = (reducedValue.Sites[i].AddressExists / reducedValue.Sites[i].Count) * 100; currentSite.PhotosExists = (reducedValue.Sites[i].PhotosExists / reducedValue.Sites[i].Count) * 100; currentSite.CategoriesExists = (reducedValue.Sites[i].CategoriesExists / reducedValue.Sites[i].Count) * 100; currentSite.HoursOfOperationExists = (reducedValue.Sites[i].HoursOfOperationExists / reducedValue.Sites[i].Count) * 100; currentSite.DescriptionExists = (reducedValue.Sites[i].DescriptionExists / reducedValue.Sites[i].Count) * 100; currentSite.CompletenessScore = 0; var total = 0; var length = internal_site_exists(currentSite.Name, rules) if (length == -1) { currentSite.CompletenessScore = (currentSite.BusinessNameExists + currentSite.PhoneExists + currentSite.AddressExists + currentSite.WebSiteExists + currentSite.PhotosExists + currentSite.CategoriesExists + currentSite.HoursOfOperationExists + currentSite.DescriptionExists) / 8; } else { if (!(internal_exists("BusinessName", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.BusinessNameExists; total++; } if (!(internal_exists("Phone", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.PhoneExists; total++; } if (!(internal_exists("WebSite", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.WebSiteExists; total++; } if (!(internal_exists("Address", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.AddressExists; total++; } if (!(internal_exists("Photos", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.PhotosExists; total++; } if (!(internal_exists("Categories", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.CategoriesExists; total++; } if (!(internal_exists("HoursOfOperation", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.HoursOfOperationExists; total++; } if (!(internal_exists("Description", rules[length].Fields))) { currentSite.CompletenessScore += currentSite.DescriptionExists; total++; } currentSite.CompletenessScore = currentSite.CompletenessScore / total; } modifiedDocument.Sites.push(currentSite); } return modifiedDocument; }, scope: { internal_exists: function (value, array) { for (var i = 0; i < array.length; i++) if (value == array[i]) return true; return false; }, internal_rule: function () { var RULES = [{ "sites": "Bing", "Fields": ["Categories", "Description"] }, { "sites": "Google", "Fields": ["Description"] }, { "sites": "Facebook", "Fields": ["Categories", "HoursOfOperation", "Description"] }, { "sites": "Foursquare", "Fields": ["HoursOfOperation"] }, { "sites": "Zomato", "Fields": ["Description"] } ]; return RULES; }, internal_site_exists: function (value, array) { for (var i = 0; i < array.length; i++) if (value == array[i].sites) return i; return -1; } } }) }