0
votes

I need to retrieve a set of answers according to 2 attributes.

This is what i want to do:

# where liker_ids is an array and user_id is a bson in the answer document
feed_answers=Answer.any_in(:liker_ids=>to_use,:user_id.in=>to_use).desc()map{|a|a}

What i ended up doing:

# to use 
to_use=[some array of ids]
friend_answers=Answer.any_in(:liker_ids=>to_use).map{|a|a}
liked_answers=Answer.where(:user_id.in=>to_use).map{|a|a}

feed_answers=(friend_answers+ liked_answers).sort{|x,y| y.created_at<=>x.created_at}

The problem is that I do not not know how to combine the 2 queries into one. I have been trying out various combinations, but nothing seems to work. and my hacked together method is highly inefficient of course.

1

1 Answers

1
votes

You should do(Missing parameter to desc):

Answer.any_in(:liker_ids=>to_use, :user_id.in=>to_use).desc(:created_at)

But the any_in here is not correctly used, it behaves similar to where in this situation. You probably want or:

Answer.or(:liker_ids=>to_use).or(:user_id.in=>to_use).desc(:created_at)
# or
Answer.any_of({:liker_ids=>to_use}, {:user_id.in=>to_use}).desc(:created_at)
# or
Answer.or({:liker_ids=>to_use}, {:user_id.in=>to_use}).desc(:created_at)

You don't need that map at the end of criteria chain, mongoid criteria are lazy loaded, when they encounter a method which criteria do not respond to. They can also leverage mongodb cursors, so it is advised not to use map if it is not necessary. You should use Criteia#only or Criteria#without if you want to retrieve subset of fields from mongodb.