简体   繁体   中英

Permutation of array elements, as a query criteria in MongoID querying

I've got an " embedded one to many " model like the following:

class User
  include Mongoid::Document

  field :nickname
  embeds_many :watchlists
end

class Watchlist
 include Mongoid::Document

 field :html_url
 field :description
 field :tags_array, type: Array
 embedded_in :user
end

and a " criteria " for querying like the following :

User.where('watchlists.tags_array' => %w[ruby web framework])

The problem is that it match just the "exact" sequence of words presented by 'watchlists.tags_array', while I want it to match all the permutations of 'ruby', 'web' and 'framework'.

Ex.:

in case of array like: %w[ruby web framework], I need a match for all the following permutations:

ruby web framework
ruby framework web

framework web ruby 
framework ruby web

web framework ruby
web ruby framework 

Is that possible ? How can I do that ?

UPDATE:

query was a bit more complex (I was trying to semplify), it a nested kind of extraction and permutation doesn't work with either my solution nor with Sergio Tulentsev solution. It just match the exact array in both the cases:

  Object.const_set :Competitor, Struct.new(:html_url, :description, :watchers, :forks)
  def self.find_competitors(tags_array)
    competitors = []
    # doesn't work:  User.where('watchlists.tags_array' => tags_array).only(:watchlists).each do |u|
    User.all_in('watchlists.tags_array' => tags_array).only(:watchlists).each do |u|
      u.watchlists.where(:tags_array => tags_array).each do |wl|
        competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks)
      end
    end
    return competitors
  end

UPDATE:

I just miss, the same ' all_in criteria ' into the inner cicle too ... and permutation works fine too :

User.all_in('watchlists.tags_array' => tags_array).only(:watchlists).each do |u|
  u.watchlists.all_in(:tags_array => tags_array).each do |wl|
    competitors << Competitor.new(wl.html_url, wl.description, wl.watchers, wl.forks)
  end
end

I think you're looking for $all operator

db.users.find({'watchlists.tags_array': { $all: ['ruby', 'web', 'framework']}});

In Mongoid speak it should be this:

User.all_in('watchlists.tags_array' => %w[ruby web framework])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM