| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = function (db, module) { | 
					
						
							|  |  |  | 	module.sortedSetIntersectCard = function (keys, callback) { | 
					
						
							|  |  |  | 		if (!Array.isArray(keys) || !keys.length) { | 
					
						
							|  |  |  | 			return callback(null, 0); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var pipeline = [ | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 			{ $match: { _key: { $in: keys } } }, | 
					
						
							|  |  |  | 			{ $group: { _id: { value: '$value' }, count: { $sum: 1 } } }, | 
					
						
							|  |  |  | 			{ $match: { count: keys.length } }, | 
					
						
							| 
									
										
										
										
											2017-02-18 01:52:56 -07:00
										 |  |  | 			{ $group: { _id: null, count: { $sum: 1 } } }, | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 		]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 16:31:16 -04:00
										 |  |  | 		db.collection('objects').aggregate(pipeline).toArray(function (err, data) { | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 			callback(err, Array.isArray(data) && data.length ? data[0].count : 0); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	module.getSortedSetIntersect = function (params, callback) { | 
					
						
							|  |  |  | 		params.sort = 1; | 
					
						
							|  |  |  | 		getSortedSetRevIntersect(params, callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	module.getSortedSetRevIntersect = function (params, callback) { | 
					
						
							|  |  |  | 		params.sort = -1; | 
					
						
							|  |  |  | 		getSortedSetRevIntersect(params, callback); | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function getSortedSetRevIntersect(params, callback) { | 
					
						
							|  |  |  | 		var sets = params.sets; | 
					
						
							|  |  |  | 		var start = params.hasOwnProperty('start') ? params.start : 0; | 
					
						
							|  |  |  | 		var stop = params.hasOwnProperty('stop') ? params.stop : -1; | 
					
						
							|  |  |  | 		var weights = params.weights || []; | 
					
						
							|  |  |  | 		var aggregate = {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (params.aggregate) { | 
					
						
							|  |  |  | 			aggregate['$' + params.aggregate.toLowerCase()] = '$score'; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			aggregate.$sum = '$score'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var limit = stop - start + 1; | 
					
						
							|  |  |  | 		if (limit <= 0) { | 
					
						
							|  |  |  | 			limit = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 		var pipeline = [{ $match: { _key: { $in: sets } } }]; | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		weights.forEach(function (weight, index) { | 
					
						
							|  |  |  | 			if (weight !== 1) { | 
					
						
							|  |  |  | 				pipeline.push({ | 
					
						
							|  |  |  | 					$project: { | 
					
						
							|  |  |  | 						value: 1, | 
					
						
							|  |  |  | 						score: { | 
					
						
							| 
									
										
										
										
											2017-02-18 00:04:34 -07:00
										 |  |  | 							$cond: { | 
					
						
							|  |  |  | 								if: { | 
					
						
							| 
									
										
										
										
											2017-02-18 01:56:23 -07:00
										 |  |  | 									$eq: ['$_key', sets[index]], | 
					
						
							| 
									
										
										
										
											2017-02-18 00:04:34 -07:00
										 |  |  | 								}, | 
					
						
							|  |  |  | 								then: { | 
					
						
							|  |  |  | 									$multiply: ['$score', weight], | 
					
						
							|  |  |  | 								}, | 
					
						
							|  |  |  | 								else: '$score', | 
					
						
							|  |  |  | 							}, | 
					
						
							| 
									
										
										
										
											2017-02-17 19:31:21 -07:00
										 |  |  | 						}, | 
					
						
							|  |  |  | 					}, | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 		pipeline.push({ $group: { _id: { value: '$value' }, totalScore: aggregate, count: { $sum: 1 } } }); | 
					
						
							|  |  |  | 		pipeline.push({ $match: { count: sets.length } }); | 
					
						
							|  |  |  | 		pipeline.push({ $sort: { totalScore: params.sort } }); | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (start) { | 
					
						
							|  |  |  | 			pipeline.push({ $skip: start }); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (limit > 0) { | 
					
						
							|  |  |  | 			pipeline.push({ $limit: limit }); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-18 12:30:49 -07:00
										 |  |  | 		var project = { _id: 0, value: '$_id.value' }; | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 		if (params.withScores) { | 
					
						
							|  |  |  | 			project.score = '$totalScore'; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		pipeline.push({ $project: project }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 16:31:16 -04:00
										 |  |  | 		db.collection('objects').aggregate(pipeline).toArray(function (err, data) { | 
					
						
							| 
									
										
										
										
											2016-12-23 14:12:00 +03:00
										 |  |  | 			if (err || !data) { | 
					
						
							|  |  |  | 				return callback(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!params.withScores) { | 
					
						
							|  |  |  | 				data = data.map(function (item) { | 
					
						
							|  |  |  | 					return item.value; | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			callback(null, data); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-02-18 02:30:48 -07:00
										 |  |  | }; |