Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
147 views
in Technique[技术] by (71.8m points)

javascript - Implementing MongoDB 2.4's full text search in a Meteor app

I'm looking into adding full text search to a Meteor app. I know MongoDB now supports this feature, but I have a few questions about the implementation:

  • What's the best way to enable the text search feature (textSearchEnabled=true) in a Meteor app?
  • Is there a way to add an index (db.collection.ensureIndex()) from within your app?
  • How can you run a Mongo command (i.e. db.quotes.runCommand( "text", { search: "TOMORROW" } )) from within a Meteor app?

Since my goal is to add search to Telescope, I'm searching for a "plug-and-play" implementation that requires minimal command line magic and could even work on Heroku or *.meteor.com.

question from:https://stackoverflow.com/questions/17159626/implementing-mongodb-2-4s-full-text-search-in-a-meteor-app

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The simplest way without editing any Meteor code is to use your own mongodb. Your mongodb.conf should look something like this (on Arch Linux it is found at /etc/mongodb.conf)

bind_ip = 127.0.0.1
quiet = true
dbpath = /var/lib/mongodb
logpath = /var/log/mongodb/mongod.log
logappend = true
setParameter = textSearchEnabled=true

The key line is setParameter = textSearchEnabled=true, which, as it states, enables text search.

Start mongod up

Tell meteor to use your mongod not its own by specifying the MONGO_URL environmental variable.

MONGO_URL="mongodb://localhost:27017/meteor" meteor

Now say you have collection called Dinosaurs declared say in collections/dinosaurs.js

Dinosaurs = new Meteor.Collection('dinosaurs');

To create an text index for the collection create a file server/indexes.js

Meteor.startUp(function () {
    search_index_name = 'whatever_you_want_to_call_it_less_than_128_characters'

    // Remove old indexes as you can only have one text index and if you add 
    // more fields to your index then you will need to recreate it.
    Dinosaurs._dropIndex(search_index_name);

    Dinosaurs._ensureIndex({
        species: 'text',
        favouriteFood: 'text'
    }, {
        name: search_index_name
    });
});

Then you can expose the search through a Meteor.method, for example in the file server/lib/search_dinosaurs.js.

// Actual text search function
_searchDinosaurs = function (searchText) {
    var Future = Npm.require('fibers/future');
    var future = new Future();
    Meteor._RemoteCollectionDriver.mongo.db.executeDbCommand({
        text: 'dinosaurs',
        search: searchText,
        project: {
          id: 1 // Only take the ids
        }
     }
     , function(error, results) {
        if (results && results.documents[0].ok === 1) {
            future.ret(results.documents[0].results);
        }
        else {
            future.ret('');
        }
    });
    return future.wait();
};

// Helper that extracts the ids from the search results
searchDinosaurs = function (searchText) {
    if (searchText && searchText !== '') {
        var searchResults = _searchEnquiries(searchText);
        var ids = [];
        for (var i = 0; i < searchResults.length; i++) {
            ids.push(searchResults[i].obj._id);
        }
        return ids;
    }
};

Then you can publish only documents that have been searched for in 'server/publications.js'

Meteor.publish('dinosaurs', function(searchText) {
    var doc = {};
    var dinosaurIds = searchDinosaurs(searchText);
    if (dinosaurIds) {
        doc._id = {
            $in: dinosaurIds
        };
    }
    return Dinosaurs.find(doc);
});

And the client side subscription would look something like this in client/main.js

Meteor.subscribe('dinosaurs', Session.get('searchQuery'));

Props to Timo Brinkmann whose musiccrawler project was the source of most this knowledge.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...