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

Posted

技术标签:

【中文标题】在 Meteor 应用程序中实现 MongoDB 2.4 的全文搜索【英文标题】:Implementing MongoDB 2.4's full text search in a Meteor app 【发布时间】:2013-06-14 02:55:00 【问题描述】:

我正在考虑向 Meteor 应用程序添加全文搜索。我知道 MongoDB 现在支持此功能,但我对实现有一些疑问:

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

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

【问题讨论】:

文本搜索仅在 Mongo 2.4 中提供预览。因此,我认为它没有被曝光。 我知道它还没有正式曝光,但这并不意味着没有办法。 文本搜索未公开。它是开源的,因此您可以添加所需的内容并自己托管。文本搜索尚未被“证明”,并且可能不会比 ElasticSearch/Solr/Lucene 搜索引擎更好。 ***.com/questions/14567856/… 想知道这个答案是否仍然是截至 2014 年 9 月的最佳答案? 【参考方案1】:

不编辑任何 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向上

通过指定MONGO_URL 环境变量,告诉meteor 使用你的mongod 而不是它自己的。

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 是大部分此类知识的来源。

【讨论】:

把它带到这里并给你信用meteorpedia.com/read/Fulltext_search 太棒了!需要注意的一点:此发布不会是实时的,因为用户永远不会获得与搜索匹配的新恐龙等。 @StephanTual Thimo Brinkmann 指出在 Google 网上论坛上使用 MongoInternals.defaultRemoteCollectionDriver().mongo.db.executeDbCommand groups.google.com/d/msg/meteor-talk/x9kYnO52Btg/YaWrYLZSKJQJ 从 0.6.6.3.pre 更新语法 -- MongoInternals.defaultRemoteCollectionDriver().mongo._getCollection('my_collection') 我不确定最好发布/订阅此搜索,这对于大多数搜索功能来说似乎是一种浪费,因为方法调用的资源密集度要少得多。如果您在搜索中使用限制,则必须处理取消订阅。我可以看到 pub/sub 的用途,但我不认为像这样的一般示例是一个很好的例子。 :p 只是我的 2c【参考方案2】:

创建一个文本索引并尝试像这样添加我希望这样如果仍然有问题评论会很有用

来自docs.mongodb.org:


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

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

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

使用文本中的项目选项仅返回 索引,如下所示:

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

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

【讨论】:

-1 用于从docs.mongodb.org 复制和粘贴,无需参考。 rtfm +50。问题是恕我直言仍然没有答案。缺少流星上下文。

以上是关于在 Meteor 应用程序中实现 MongoDB 2.4 的全文搜索的主要内容,如果未能解决你的问题,请参考以下文章

在 Node JS 应用程序中实现单例 mongoDB DB 对象

如何将流星连接到现有后端?

在mongodb中实现分页

我应该如何在 MongoDB 中实现这个模式?

如何在 node.js 和 mongodb 中实现 geoip

Meteor:Minimongo 不与 MongoDB 同步