2

I have a class Post, with the following scope:

scope :by_tag, ->(tag){ where(:desc => /##{Regexp.escape(tag)}/) }

It works very well with one tags, but I can't make it work with various tags.

For example: I cant make it give me the posts tagged with #rails AND #regexp.

With criteria union I can make it return me the posts tagged with #rails OR #regexp.

How can I get it to work? I'm using mongoid, btw.

Thanks in advance.


Just fount that is not an OR. What happens is that the second time I call by_tag, it overrides the previous. I believe that's because it's the same property.

Someone know how to fix this? Thanks

1 Answer 1

1

Regexp queries tend to be really slow. Instead, store an array of tags and use $in to query the array.

With Mongoid 2.x use all_in

scope :by_tags, ->(*tags) { all_in(tags: *tags) }

With Mongoid 3 use all merge strategy

scope :by_tags, ->(*tags) { all(tags: *tags) }
Sign up to request clarification or add additional context in comments.

4 Comments

very interesting. I'll try it at home tonight. Thank you very much!
by the way: I can pass a array of tags, and it will automatically find the items that contains all tags passed? Ex: Post.by_tags '#mongo', '#rails' will return me the item Post with desc= 'testing #mongo in #rails'? That easy?
No, the desc field must be stored as array. If you want to keep the desc field as string like it is, add a new field (e.g. tags) that you set when storing the desc that contains the list of tags extracted from the desc. Then, you'll be able to query it with by_tags
got that... I'll have to do that anyway to made my life a bit easier in other places of the app. thanks man, at night I give you some feedback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.