Making User Recommendations


(Andrew Wong) #1

Hi, I am new to Elasticsearch and am trying to use Elasticsearch to create a simple recommendation engine that recommends friends to users. I have an index consisting of users which have the properties like so:

  "id": 1000,
  "first_name": "john",
  "last_name": "john",
  "email": "test@email.com",
  "friends": [1001]

For example, the user above has id 1000 and I could query the user's friends with id 1001. What I would like to do is be able to query into user 1001's friends, and then return a filtered result of users whom are not user 1000's friends.

For clarity, if user 1001 is friends with user 1002 and 1003, I would like to have the response with these ids given that user 1002 and 1003 are not friends with user 1001.

My first attempt on this query:

GET _search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "id": 1000
          }
        }
      ]
    }
  },
  "aggs": {
    "recommended_friends": {
      "terms": {
        "field": "friends",
        "size": 10
      }
    }
  }
}

The aggregation above returns a bucket of user 1000's friends. Then, I attempted to modify the aggregation again with:

  "aggs": {
    "recommended_friends": {
      "filter": {
        "term": {
          "id": 1000
        }
      },
      "aggs": {
        "friends": {
          "terms": {
            "field": "friends"
          }
        }
      }
    }
  }

In the first aggregation with id:1000, I was just trying to filter out user 1000's friends. I am lost here and have been wondering if I am approaching this query the correct way. Is it possible to perform such a query in a single search?


(Andrew Wong) #2

I think I have found the solution. I am not sure if this is the best way of doing things but am still trying to find the best practices using elasticsearch.

I have modified the query to have a nested aggregation under the friends term as it will allow me to perform an extra query to get a user's friend's friends and then using an exclude query, I just have to input the user's IDs and the user's friends IDs. As such, this will filter out all users that the user is friends with and the remainder in the bucket is essentially the "recommended" friends.


(ddorian43) #3
  1. do GET to return user's 1000 friends array
  2. do an aggregation query with exclude for those friends "where ID in my_friends AND their_friends NOT IN my_friends`

Makes sense ?


(Andrew Wong) #4

Hi @ddorian43!

Thank you for the reply! That was the trick, a nested aggregation with the 'exclude' clause used within this subquery.


(system) #5

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.