0

I am currently developing a "dating" website as a school project. I'm using Node.js, Express, my SQL, and Pug (Jade).

So far, my users have profile pages and in database I have the following information regarding them:

  • Age
  • Sexual orientation
  • Sex
  • Location (latitude and longitude, country, and exact city)
  • Tags (words that defines them the best)

Now that I have all of this, my user has to be able the search by:

  • Age
  • Location and tags.

I am supposed to render by order, and the first match should always be the closest by location.

How do I sort all of theses information to check if any of my users can match one or several persons?

VLAZ
  • 26,331
  • 9
  • 49
  • 67
pkerckhove
  • 763
  • 2
  • 10
  • 17

1 Answers1

0

You could loop through all users in your database and calculate a score. Points are e.g. rewarded based on how near they are. In the end, the person with the most points will be the best match.


Here is an example with some randomly generated data.
I made the assumption

  • that every person is interested in the opposite sex
  • that latitude and longitude are coordinates on a plane in order to use the Pythagorean theorem to calculate distance

let data = [
  {
    'name': 'John Doe',
    'sex': 'male',
    'pos': [ 43.036871, -89.324967 ],
    'tags': [ 'general', 'basic' ]
  },
  {
    'name': 'Amy Schmidt',
    'sex': 'female',
    'pos': [ 39.48586, -121.387316 ],
    'tags': [ 'honest', 'uneven' ]
  },
  {
    'name': 'Robert Summers',
    'sex': 'male',
    'pos': [ 33.657366, -86.643871 ],
    'tags': [ 'efficient', 'psychotic' ]
  },
  {
    'name': 'Steven Walls',
    'sex': 'male',
    'pos': [ 43.484856, -83.849829 ],
    'tags': [ 'huge', 'grumpy' ]
  },
  {
    'name': 'Elizabeth Bateman',
    'sex': 'female',
    'pos': [ 38.886231, -99.306865 ],
    'tags': [ 'heavy', 'goofy' ]
  },
  {
    'name': 'Robert Galusha',
    'sex': 'male',
    'pos': [ 29.713645, -95.534338 ],
    'tags': [ 'vast', 'depressed' ]
  }
];

function search(person, tags) {
  let scores = { }, distances = { },
      lat = person.pos[0], lng = person.pos[1];
  
  data.filter(user => user.name !== person.name).forEach(user => {
    scores[user.name] = 0;
    scores[user.name] += user.tags.filter(tag => tags.indexOf(tag) > -1).length;
    scores[user.name] += user.sex !== person.sex ? 1 : 0;
    
    let dlat = Math.abs(lat - user.pos[0]), dlng = Math.abs(lng - user.pos[1]),
        distance = Math.sqrt(Math.pow(dlat, 2) + Math.pow(dlng, 2));
    
    distances[user.name] = distance;
  });
  
  // Needed to normalize the distances
  let maxDistance = Object.values(distances).sort((a, b) => b - a).shift();
  
  for(let name in distances)
    // Substract the normalized distance from 1, so: shorter distance = more points
    scores[name] += (1 - distances[name] / maxDistance);
  
  // Sort by score; the best match is the first element
  return Object.entries(scores).sort((a, b) => b[1] - a[1]);
}

console.log(search(data[0], [ 'honest', 'vast' ]))

If you want some factors to have a heavier impact on the overall score than others, you can multiply them by a certain weight.

schroffl
  • 579
  • 7
  • 17
  • Wow thank you very much ! This might be the perfect answer. And you are using promises, I'm trying to learn them during this project. Instead of the Pythagorean theorem I was about to use : http://stackoverflow.com/questions/365826/calculate-distance-between-2-gps-coordinates But I guess I'll try both. Anyway thank you for your help, I'll let you know if I made it to work. Cheers. – pkerckhove Dec 26 '16 at 15:10
  • I'm not entirely sure if using the pythagorean theorem works in all cases, so you'll have to check that. And where did I use promises? – schroffl Dec 26 '16 at 15:11
  • Oh my bad, I though the LET was meant to be used with promises. I'm new to Javascript and Node.Js. Not sure about the pythagorean theorem but I'll try it anyway ! – pkerckhove Dec 26 '16 at 15:14
  • No, `let` is just a way to declare a variable. It was introduced in ES6 along with `const` and both are, unlike `var`, block-scoped. – schroffl Dec 26 '16 at 15:18
  • Ok, no idea about that, thanks for the informations ! – pkerckhove Dec 28 '16 at 16:14