在Meteor应用程序中实现MongoDB 2.4的全文搜索

时间:2013-06-18 02:19:36

标签: javascript mongodb search meteor

我正在考虑将全文搜索添加到Meteor应用程序中。我知道MongoDB现在支持这个功能,但是我对这个实现有几个问题:

  • 在Meteor应用中启用文本搜索功能(textSearchEnabled=true)的最佳方法是什么?
  • 有没有办法在您的应用中添加索引(db.collection.ensureIndex())?
  • 如何在Meteor应用程序中运行Mongo命令(即db.quotes.runCommand( "text", { search: "TOMORROW" } ))?

由于我的目标是将搜索添加到Telescope,我正在寻找一种“即插即用”的实现,它需要最少的命令行魔法,甚至可以在Heroku或* .meteor.com上运行。

2 个答案:

答案 0 :(得分:27)

没有编辑任何Meteor代码的最简单方法是使用您自己的mongodb。您的mongodb.conf看起来应该是这样的(在Arch Linux上,它位于/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

关键行是setParameter = textSearchEnabled=true,正如其所述,它可以启用文本搜索。

开始mongod向上

通过指定mongod环境变量,告诉meteor使用您的MONGO_URL而不是自己的。{/ p>

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

现在假设您在Dinosaurs

中声明了名为collections/dinosaurs.js的集合
Dinosaurs = new Meteor.Collection('dinosaurs');

要为集合创建文本索引,请创建文件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
    });
});

然后,您可以通过Meteor.method公开搜索,例如在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;
    }
};

然后,您只能发布在'server / publications.js'

中搜索过的文档
Meteor.publish('dinosaurs', function(searchText) {
    var doc = {};
    var dinosaurIds = searchDinosaurs(searchText);
    if (dinosaurIds) {
        doc._id = {
            $in: dinosaurIds
        };
    }
    return Dinosaurs.find(doc);
});

客户端订阅在client/main.js

中看起来像这样
Meteor.subscribe('dinosaurs', Session.get('searchQuery'));

支持Timo Brinkmann musiccrawler project,其中{{3}}是大多数此类知识的来源。

答案 1 :(得分:2)

要创建文本索引并尝试添加这样的内容,我希望如果仍然存在问题评论将会很有用

来自docs.mongodb.org


  

将标量索引字段附加到文本索引,如下所示   示例,它指定用户名上的升序索引键:

db.collection.ensureIndex( { comments: "text",
                             username: 1 } )
     

警告您不能包含多键索引字段或地理空间索引   字段。

     

使用文本中的项目选项仅返回中的字段   index,如下所示:

db.quotes.runCommand( "text", { search: "tomorrow",
                                project: { username: 1,
                                           _id: 0
                                         }
                              }
                    )
     

注意:默认情况下,_id字段包含在结果集中。由于示例索引不包含_id字段,因此必须   明确排除项目文档中的字段。