MongoDB 2.6 MongoMapper Text Index

141 views
Skip to first unread message

Greg Braman

unread,
Apr 21, 2014, 2:19:53 PM4/21/14
to mongo...@googlegroups.com
Hi all,

I'm trying to enable multi-field full-text search (http://docs.mongodb.org/manual/tutorial/create-text-index-on-multiple-fields/) using MongoMapper v0.13.0.beta2. I have tried `Collection.ensure_index(["$**", "text"])`, but I get the following error:

ruby-1.9.3-p545@actionlog/gems/mongo-1.8.3/lib/mongo/collection.rb:1028:in `parse_index_spec': Invalid index specification ["$**", "text"]; should be either a hash (OrderedHash), string, symbol, or an array of arrays. (Mongo::MongoArgumentError)

Does anybody have any experience with this or any ideas how to enable this index using .ensure_index?

Thanks.

Greg Braman

unread,
Apr 21, 2014, 3:21:08 PM4/21/14
to mongo...@googlegroups.com
Update: I think I've figured this out. I added `Finding.ensure_index({ "$**" => "text" })` and now I can query using $text and $search like this:

`findings = Finding.where({"$text" => {"$search" =>  "sweet potato" }})`

This will now return a collection of findings where any text field matches 'sweet' OR 'potato'. You can also use all of the mongodb text search hotness like "sweet -potato" where the document contains "sweet" and doesn't contain "potato". Or searching with string literals like \a literal string\.

Jon Kern

unread,
Apr 21, 2014, 5:08:25 PM4/21/14
to mongo...@googlegroups.com
--
You received this message because you are subscribed to the Google
Groups "MongoMapper" group.
For more options, visit this group at
http://groups.google.com/group/mongomapper?hl=en?hl=en
---
You received this message because you are subscribed to the Google Groups "MongoMapper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongomapper...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Heald

unread,
Apr 23, 2014, 10:11:58 AM4/23/14
to mongo...@googlegroups.com
Very cool. We should probably provide a plugin to help streamline this!

Greg Braman

unread,
Apr 24, 2014, 11:25:26 AM4/24/14
to mongo...@googlegroups.com
Hey Chris,

Do you think this should be added as a mongomapper plugin or a separate gem?

Chris Heald

unread,
Apr 24, 2014, 11:31:08 AM4/24/14
to mongo...@googlegroups.com
Either-or. It would be a plugin in either case, but it could be published in a separate gem. I think it belongs in the core distro though, since full-text search is a full Mongo feature now.

Tangentially, I have a little custom plugin I use to let me define indexes on the model. Would this be useful in master to people? The idea is that I have:

    class Page
      include MongoMapper::Document

      key :url, String, alias: :u
      # ...

      indexes do
        ensure_index :u, unique: true
        ensure_index :dm
        ensure_index :a
        ensure_index :src
        ensure_index [[:ls, 1], [:u, 1]]
      end
    end

Additionally, I add a ::index! method to MongoMapper::Document, so that I can index my models when convenient (deploy, app boot, etc, as appropriate)

I remember that once upon a time, MM had inline indexes on fields, but that was deprecated as it produced somewhat undesirable behavior. However, it seems like it might be useful to have a DSL to define indexes that could be lazy-invoked by the application as is most appropriate. Thoughts?

Greg Braman

unread,
Apr 24, 2014, 11:59:58 AM4/24/14
to mongo...@googlegroups.com
Chris,

I like this method; +1 from me. How do you handle indexes for embedded documents using this? Do you just define the embedded indexes on the parent document? Also, I like the idea of merging these document level indexes with a DSL for full-text search. Something like:


    class Page
      include MongoMapper::Document
      include MongoMapper::FullTextSearch

      key :url, String, alias: :u
      # ...

      indexes do
        ensure_index :all                        # The equivalent of Page.ensure_index(["$**", "text"]); This generates a composite text index for all fields in the model.
        ensure_index :only => [:u]
        ensure_index :except => [:u]
      end
    end

Thoughts?

Chris Heald

unread,
Apr 24, 2014, 12:42:53 PM4/24/14
to mongo...@googlegroups.com
Yeah, embedded documents just get defined on the parent right now. I need to flesh it out so that you can define them on the embedded doc, though, if it were to be provided in master.

I think I'd clean up the DSL a bit, so that we could do something like:

indexes do
index :username
index {signup_date: 'asc', post_count: 'desc'}, unique: true

# Index all fields
fulltext_index_all

# All except `u`
fulltext_index_all except: [:u]

# Only `u` and `v`
fulltext_index [:u, :v]
end

We'd also need to support a DSL for geospatial indexes and the like, as well.




--
Reply all
Reply to author
Forward
0 new messages