Rails Mongoid `pluck` equivalent?

4.9k Views Asked by At

In my Rails app I am using MongoID with a Elasticsearch river for text search.

For @devices_with_config = ConfigTextSearch.search params[:device_id] I want to extract just the device_id fields for the matching records in the query. In mongoID 3.1.0 I could just use Band.all.pluck(:name). But unfortunately, I am stuck with 3.0.23.

I see there is a similar moped expression collections[:bands].find.select(name: 1)...but I am new to rails and can't figure out how I would use a moped expression in a controller or model.

Any Ideas on how I can just extract the 'device_id' field in matches with MongoId?

6

There are 6 best solutions below

4
Sergio Tulentsev On

You can get a hold of a Moped collection like this

 Band.collection.find.select(name: 1)
0
dman On

Found it....from what I can tell this isn't on the MongoId docs.....

sue = bob.results.map { |r| r._source.device_id }

0
Mike S On

Mongoid has a pluck function now.

mongoid#pluck

0
Jay On

It seems like you're not actually building a Mongoid criteria with that call, but I haven't looked into elasticsearch-rails so I can't be 100% sure.

If you're completely unable to update to 3.1.0 you should be able to just monkey patch this functionality in.

module Mongoid
  class Criteria
    # select specific fields from collection based on current scope, returned as a hash
    def pluck(*fields)
      raise ArgumentError, 'Call this with at least one field' if fields.empty?

      collection.find(self.selector).select(Hash[fields.map { |field| [field, 1] }]).to_a
    end
  end
end

After adding the above code you should be able to do the following:

Band.where(name: 'awesome').pluck(:id, :device_id)
1
Pushp Raj Saurabh On

An equivalent to the pluck method defined in mongoid is:

plucked_array = User.where(:name => 'xyz').map(&: field_to_be_plucked)

Where field_to_be_plucked is the name of the field whose values need to be plucked out in Array.

2
Brilnius On

What I used for the same purpose, with Mongoid 3.0 :

Band.all.distinct(:name)

Warning: relevant only if all the names are different (of if you want to remove duplicates).