Explorar el Código

Merge branch 'filter-before-scoring' of fyindr/siimee into dev

tags/0.0.3^2
maeda hace 2 años
padre
commit
62847c7392

+ 1
- 1
backend/db/seeds/04-responses.js Ver fichero

@@ -28,7 +28,7 @@ exports.seed = async knex => {
28 28
     for (let i = 1; i <= len; i += 1) {
29 29
         responsesToPush.push(responses.shift())
30 30
         if (i % batchSize === 0 || i > responses.length) {
31
-            await knex('responses').insert(responsesToPush)
31
+            // await knex('responses').insert(responsesToPush)
32 32
             responsesToPush = []
33 33
         }
34 34
     }

+ 6
- 0
backend/lib/routes/profile/score.js Ver fichero

@@ -53,11 +53,17 @@ module.exports = {
53 53
             const distanceUnit = request.query.unit
54 54
                 ? request.query.unit
55 55
                 : 'mile'
56
+            const duration = request.query.duration
57
+            const presence = request.query.presence
58
+            const certifications = request.query.certifications
56 59
 
57 60
             const scoredProfiles = await profileService.scoreProfilesFor(
58 61
                 profileId,
59 62
                 maxDistanceMiles,
60 63
                 distanceUnit,
64
+                duration,
65
+                presence,
66
+                certifications,
61 67
             )
62 68
             try {
63 69
                 if (!scoredProfiles) {

+ 48
- 0
backend/lib/services/filter.js Ver fichero

@@ -0,0 +1,48 @@
1
+const zipcoder = require ('./profile/zipcoder')
2
+
3
+const byProfileType = (profileList, userProfile) => {
4
+    const isUserOpposite = userProfile.is_poster == 1 ? 0 : 1
5
+    return profileList.filter(profile => (profile.user.is_poster == isUserOpposite))
6
+}
7
+const byNullZip = (profileList) => {
8
+    return profileList.filter(profile => {
9
+        return zipcoder.getZipCodeFromProfile(profile) ? true : false
10
+    })
11
+}
12
+const byMaxDistance = (profileList, max) => {
13
+    return profileList.filter(profile => {
14
+        const profileDistance = Math.floor(parseFloat(profile.distance) * 100)
15
+        const adjustedMaxDistance = Math.floor(parseFloat(max) * 100)
16
+        return profileDistance <= adjustedMaxDistance
17
+    })
18
+}
19
+
20
+const byDuration = (profileList, duration) => {
21
+    return profileList.filter(profile => {
22
+        // TODO find duration 
23
+        return profile.duration == duration
24
+    })
25
+}
26
+
27
+const byPresence = (profileList, presence) => {
28
+    return profileList.filter(profile => {
29
+        // TODO find presence 
30
+        return profile.presence == presence
31
+    })
32
+}
33
+
34
+const byCertifications = (profileList, certifications) => {
35
+    return profileList.filter(profile => {
36
+        // TODO find certifications 
37
+        return profile.certifications == certifications
38
+    })
39
+}
40
+
41
+module.exports = {
42
+    byProfileType,
43
+    byNullZip,
44
+    byMaxDistance,
45
+    byDuration,
46
+    byPresence,
47
+    byCertifications,
48
+}

+ 38
- 33
backend/lib/services/profile/index.js Ver fichero

@@ -4,7 +4,7 @@ const config = require('../../../db/data-generator/config.json')
4 4
 const profiler = require('./profiler')
5 5
 const scoring = require('./scorer')
6 6
 const zipcoder = require('./zipcoder')
7
-const { response } = require('@hapi/hapi/lib/validation')
7
+const filter = require('../filter')
8 8
 
9 9
 module.exports = class ProfileService extends Schmervice.Service {
10 10
     constructor(...args) {
@@ -243,7 +243,14 @@ module.exports = class ProfileService extends Schmervice.Service {
243 243
      * @param {number} profileId
244 244
      * @returns {Array} Ordered and scored Profiles
245 245
      */
246
-    async scoreProfilesFor(profileId, maxDistance, distanceUnit) {
246
+    async scoreProfilesFor(
247
+        profileId,
248
+        maxDistance,
249
+        distanceUnit,
250
+        duration,
251
+        presence,
252
+        certifications,
253
+    ) {
247 254
         const { Profile } = this.server.models()
248 255
 
249 256
         await this._setScoreLookup()
@@ -254,29 +261,41 @@ module.exports = class ProfileService extends Schmervice.Service {
254 261
             .withGraphFetched('responses')
255 262
             .withGraphFetched('user')
256 263
 
257
-        // Move unneeded responses
258 264
         const userZip = zipcoder.getZipCodeFromProfile(userProfile)
259 265
 
260
-        // Find all Profiles that are NOT of our userProfile.type
261
-        // ie. If userProfile.type == seeker, then find: poster
262
-        let profileIdsOfOppositeType = await Profile.query()
266
+        // preprocess potential match pool with filter service methods
267
+        let matchPool = await Profile.query()
263 268
             .withGraphFetched('responses')
264 269
             .withGraphFetched('user')
265
-        // TODO: Let Objection optimize this
266
-        const isPosterOpposite = userProfile.user.is_poster == 1 ? 0 : 1
267
-        profileIdsOfOppositeType = profileIdsOfOppositeType
268
-            .filter(profile => {
269
-                return profile.user.is_poster == isPosterOpposite
270
-            })
271
-            .filter(profile => {
272
-                // Only include profiles that included zipcode response
273
-                return zipcoder.getZipCodeFromProfile(profile) ? true : false
274
-            })
275 270
 
276
-        const profilePlusDistance = await Promise.all(
277
-            profileIdsOfOppositeType.map(async profile => {
278
-                const targetZip = zipcoder.getZipCodeFromProfile(profile)
271
+        matchPool = filter.byProfileType(matchPool, userProfile.user)
272
+        matchPool = filter.byNullZip(matchPool)
273
+        // attach distance to pool profiles for max distance filter
274
+        matchPool = await this.calcProfileDistances(
275
+            matchPool,
276
+            distanceUnit,
277
+            userZip,
278
+        )
279
+        matchPool = filter.byMaxDistance(matchPool, maxDistance)
280
+        matchPool = filter.byDuration(matchPool, duration)
281
+        matchPool = filter.byPresence(matchPool, presence)
282
+        matchPool = filter.byCertifications(matchPool, certifications)
279 283
 
284
+        const scoredProfilesWithDistance = scoring.scoreAll(
285
+            matchPool,
286
+            userProfile,
287
+            this.scoreLookup,
288
+        )
289
+        // Order by score
290
+        return scoredProfilesWithDistance.sort(
291
+            (a, b) => b.score.total - a.score.total,
292
+        )
293
+    }
294
+
295
+    async calcProfileDistances(matchPool, distanceUnit, userZip) {
296
+        await Promise.all(
297
+            matchPool.map(async profile => {
298
+                const targetZip = zipcoder.getZipCodeFromProfile(profile)
280 299
                 if (!userZip || !targetZip)
281 300
                     return { ...profile, distance: [9999, distanceUnit] }
282 301
 
@@ -291,20 +310,6 @@ module.exports = class ProfileService extends Schmervice.Service {
291 310
                 }
292 311
             }),
293 312
         )
294
-
295
-        const distanceFilteredProfiles = zipcoder.filterByDistance(
296
-            profilePlusDistance,
297
-            maxDistance,
298
-        )
299
-        const scoredProfilesWithDistance = scoring.scoreAll(
300
-            distanceFilteredProfiles,
301
-            userProfile,
302
-            this.scoreLookup,
303
-        )
304
-        // Order by score
305
-        return scoredProfilesWithDistance.sort(
306
-            (a, b) => b.score.total - a.score.total,
307
-        )
308 313
     }
309 314
 
310 315
     /**

+ 0
- 9
backend/lib/services/profile/zipcoder.js Ver fichero

@@ -11,15 +11,6 @@ const getZipCodeFromProfile = profile => {
11 11
     return zipRes.val
12 12
 }
13 13
 
14
-const filterByDistance = (profileList, max) => {
15
-    return profileList.filter(profile => {
16
-        const profileDistance = Math.floor(parseFloat(profile.distance) * 100)
17
-        const adjustedMaxDistance = Math.floor(parseFloat(max) * 100)
18
-        return profileDistance <= adjustedMaxDistance
19
-    })
20
-}
21
-
22 14
 module.exports = {
23 15
     getZipCodeFromProfile,
24
-    filterByDistance,
25 16
 }

+ 218
- 7115
backend/package-lock.json
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 2
- 1
frontend/src/main.js Ver fichero

@@ -8,7 +8,8 @@ import components from './wave'
8 8
 import App from './App.vue'
9 9
 import MainNav from './components/MainNav.vue'
10 10
 
11
-const DEV = import.meta.env.VITE_DEV == 'true'
11
+// const DEV = import.meta.env.VITE_DEV == 'true'
12
+const DEV = false
12 13
 
13 14
 /**
14 15
  * Check between route changes for login/timeout

+ 8
- 2
frontend/src/services/survey.service.js Ver fichero

@@ -49,9 +49,15 @@ const updateSurveyByProfileId = async (surveyResponses, profileId) => {
49 49
     })
50 50
 }
51 51
 
52
-const scoreSurveyByProfileId = async (profileId, maxDistance = 99) => {
52
+const scoreSurveyByProfileId = async (
53
+    profileId,
54
+    maxDistance = 99,
55
+    duration,
56
+    presence,
57
+    certifications,
58
+) => {
53 59
     const scoreSurvey = await db.get(
54
-        `/profile/${profileId}/score?max_distance=${maxDistance}`,
60
+        `/profile/${profileId}/score?max_distance=${maxDistance}&duration=${duration}&presence=${presence}&certifications=${certifications}`,
55 61
     )
56 62
     return scoreSurvey
57 63
 }

+ 1
- 1
frontend/src/utils/lang.js Ver fichero

@@ -32,7 +32,7 @@ const auth = {
32 32
 // Easily reorder steps of survey here:
33 33
 const allSteps = {
34 34
     usa: {
35
-        email: 'email',
35
+        splash: 'splash',
36 36
         name: 'name',
37 37
         seeking: 'seeking',
38 38
         password: 'password',

+ 24
- 1
frontend/src/views/SurveyView.vue Ver fichero

@@ -207,7 +207,13 @@ export default {
207 207
 
208 208
             return userProfileRel
209 209
         },
210
-        async _getProfileWithScore(createdProfileId, maxDistance) {
210
+        async _getProfileWithScore(
211
+            createdProfileId,
212
+            maxDistance,
213
+            duration,
214
+            presence,
215
+            certifications,
216
+        ) {
211 217
             /** A Profile is associated with n:1 user and referenced by profile id */
212 218
             const fetchedProfile = await fetchProfileByProfileId(
213 219
                 createdProfileId,
@@ -223,6 +229,9 @@ export default {
223 229
             const scored = await scoreSurveyByProfileId(
224 230
                 createdProfileId,
225 231
                 maxDistance,
232
+                duration,
233
+                presence,
234
+                certifications,
226 235
             )
227 236
             if (!scored) {
228 237
                 console.error(`Could not score Profile ${createdProfileId}.`)
@@ -250,6 +259,17 @@ export default {
250 259
             const maxDistanceRes = survey.find(
251 260
                 res => res.response_key_id == distanceKey,
252 261
             )
262
+            const duration = survey.find(
263
+                res => res.response_key_id == prefKeys[1], // == 10
264
+            )
265
+            const presence = survey.find(
266
+                res => (res.response_key_id = prefKeys[2]), // == 11
267
+            )
268
+            // TODO find certifications in responses
269
+            const certifications = survey.find(
270
+                res => (res.response_key_id = certifications),
271
+            )
272
+
253 273
             /**
254 274
              * Creating a profile only returns the created
255 275
              * user id and profile id
@@ -264,6 +284,9 @@ export default {
264 284
             const fetchedProfile = await this._getProfileWithScore(
265 285
                 createdProfileId,
266 286
                 maxDistanceRes.val,
287
+                duration.val,
288
+                presence.val,
289
+                certifications.val,
267 290
             )
268 291
 
269 292
             /**

Loading…
Cancelar
Guardar