2017-08-03 47 views
1

我有类似下面的MongoDB中3.4文本搜索:MongoDB的TEXTSEARCH操作TEXTSEARCH

db.products.find({ 
    $text : { 
     $search: '"harry potter 3"' 
    } 
}, { 
    score: { 
     "$meta": "textScore" 
    }, 
    name: 1, 
    author_name: 1, 
}).sort({ 
    score: { 
     "$meta": "textScore" 
    }, 
    name: 1 
}).limit(9); 

查询按预期工作。

样本文件是:

{ 
    "_id" : ObjectId("597f17d22be7925d9a056e82"), 
    "name" : "My cool title", 
    "author_name" : "Doe, John", 
    "language" : "german", 
    "keywords" : ["harry potter", "keyword 2", "keyword 3"], 
    ... 
} 

的文本搜索索引是名称,关键字和AUTHOR_NAME。

问题:

因为我有一个讲德语的网上商店,我想在德国(语言=德语)优先文档。如果你搜索“哈利·波特3”我拿到第一个土耳其语,英语和波兰语版本(因为更高的分数,因为他们有字“哈利·波特”两次标题[不知道为什么])。

那么如何获得本本的德国版本更高的排序位置?

我想补充与{“语言”:“德国”}过滤器是不是一种选择,因为我想说明的其他结果也是如此。

理念不工作

最好的事情是要找到一种方法来提高德国书“分数”,但我不知道怎么办。这样的东西(当然不工作):

为每个文档添加一个字段language_score,并给所有德语文档一个language_score = 5,所有的英文书籍language_score = 2以及所有其他language_score = 0,然后进行排序方式:

{ 
    score: { 
     "$sum" { 
      "$meta": "textScore", 
      "language_score": "language_score" 
     } 
    }, 
    name: 1 
} 

回答

0

使用聚合框架,你可以实现你所需要的。下面的查询是未经测试的,因为我没有样本数据和指标设置的,但你的想法:

db.products.aggregate // note that we're using .aggregate() now instead of find() 
(
    { 
    $match: // that is the equivalent of your find() filter 
    { 
     $text: 
     { 
     $search: '"harry potter 3"' 
     } 
    } 
    }, 
    { 
    $project: 
    { 
     "languageScore": // here we magically compute our weight 
     { 
     $cond: 
     { 
      if: { $eq: [ "$language", "german" ] }, 
      then: "5", 
      else: 
      { 
      $cond: 
      { 
       if: { $eq: [ "$language", "english" ] }, 
       then: "2", 
       else: 0 
      } 
      } 
     } 
     }, 
     score: 
     { 
     "$meta": "textScore" 
     }, 
     name: 1, 
     author_name: 1, 
    } 
    }, 
    { 
    $sort: 
    { 
     languageScore: -1, // and then we can sort by that score 
     score: { 
     "$meta": "textScore" 
     }, 
     name: 1 
    } 
    }, 
    { $limit: 9 } 
)