使用Meteor和Mongo 2.6进行文本搜索

时间:2014-09-15 02:16:39

标签: meteor

我想在meteor(服务器端,当然)中执行相当于这个Mongo shell命令:

db.articles.find(
  { $text: { $search: "apple pie" } },
  { score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } ).limit(10)

已经能够做到:

return Articles.find( { $text: { $search: "apple" } },
{ sort: {"name":1}, limit:20});

然而,寻找"馅饼苹果"不起作用 - 它只进行精确匹配。也没有尝试按分数排序。

我在文章的名称字段中使用mongo 2.6.3和文本索引。从mongo shell中搜索工作完美。

此外,是否有人使用不同的方法成功实施了文本搜索?我的数据库有10k条目,我只需要在一个字段内搜索,并返回20个最佳匹配。

2 个答案:

答案 0 :(得分:3)

现在使用MongoDB 3.0的3个步骤(流星1.0.4+)。假设您已经拥有YourCollection集合,即

YourCollection = new Meteor.Collection("yourCollection");

一个。索引您的集合(服务器端)如下所示是如何索引所有字段more info here

Meteor.startup(function (){
        YourCollection._ensureIndex(
                {"$**": "text"},
                {"name": "searchIndex"}
        ); }

B中。创建发布(服务器端)

Meteor.publish("search-yourCollection", function(searchField)
{
    return  YourCollection.find({"$text": {"$search": searchField}},
    {
        fields: {
            score: {$meta: "textScore"}
        },
        sort: {
            score: {$meta: "textScore"}
        }
    });
});

℃。订阅出版物并找到(客户端)

var whatToSearch = "abc"; // can be taken out of the session
Meteor.subscribe("search-yourCollection", whatToSearch);
var results = YourCollection.find({score:{"$exists":true}});

备注:该出版物将为所有退回的项目添加分数属性。确保查找函数中存在此属性 {" $ exists":true} 将确保您找到 search-yourCollection 发布返回的元素。如果您订阅另一个将项添加到YourCollection已发布集中的发布,则必须这样做。

答案 1 :(得分:1)

我已经能够使用类似的东西来实现这个目的: Implementing MongoDB 2.4's full text search in a Meteor app

区别在于:

MongoInternals.defaultRemoteCollectionDriver().mongo.db.executeDbCommand

并且上面链接中的searchDinosaurs函数如下所示:

if (query && query !== '') {
var searchResults = _searchArticles(query);
var results = [];
for (var i = 0; i < searchResults.length; i++) { 
    results.push({
      id: searchResults[i].obj._id,
      score: searchResults[i].score});
}

var ids = [];

results.sort(function(a,b) { return a.score < b.score } );

for (var i = 0; i < 20; i++) {
  if (results[i]!=null){
    ids.push(results[i].id);
  }
}

return ids;

我在这里按分数对结果进行排序并返回前20名。唯一的问题是,一旦用户订阅了这20篇文章,我就必须使用minimalongo中的正则表达式搜索在客户端再次查找和排序它们。如果有人有任何建议或改进,我很乐意听到他们的意见。