MongoDB文本搜索 - 匹配字符串中的精确标记

时间:2017-05-16 12:55:30

标签: mongodb full-text-search text-search

我遇到了需要在字符串中匹配完全标记在MongoDB中进行$ text $搜索的情况。我想我可以通过创建没有默认语言的文本索引来解决这个问题,并通过用\"token\"包装每个标记来执行查询,如documentation中所述。所以我用这种方式创建了索引:

db.collection.createIndex({"denom": "text"}, {"default_language": "none"})

我必须执行的查询是

db.collection.find( {"$text": {"$search": "\"consorzio\" \"la\""}}, {"denom": 1} )

我期望的结果是所有包含令牌"consorzio""la"的文档,但此查询会匹配其标记包含字符串“la”的文档,每个令牌内的“consorzio”

例如,上面的查询返回我期望的以下denom值:

  • CONSORZIO LA * CASCINA 确定
  • LA RADA CONSORZIO 确定
  • GESCO CONSORZIO AGRICO LA 错误

有人可以解决这个问题吗?我希望问题很清楚。

非常感谢你。

2 个答案:

答案 0 :(得分:0)

Mongodb报告了此issue的错误。精确加工不起作用。

你可以看一下加工得分:

db.docs.find({$text: {$search: "\"consorzio\" \"la\""}}, 
             {score: { $meta: "textScore" }, "_id": 0})

{ "t" : "CONSORZIO LA* CASCINA OK", "score" : 1.25 } 
{ "t" : "LA RADA CONSORZIO OK", "score" : 1.25 }
{ "t" : "GESCO CONSORZIO AGRICOLA WRONG", "score" : 0.625 }

解决方案应该是考虑到最高分......

答案 1 :(得分:0)

费尔南多(Fernando),您实际上错了,它与GESCO CONSORZIO AGRICOLA WRONG匹配,但仅与您搜索的一个单词(令牌)匹配,consorzio而不是la

  

在文本搜索中,textScore大于1时   匹配查询的所有标记。

例如这是一个商店集合

db.stores.insert(
   [
     { _id: 1, name: "Java Hut", description: "Coffee and cakes" },
     { _id: 2, name: "Burger Buns", description: "Gourmet hamburgers" },
     { _id: 3, name: "Coffee Java Shop", description: "Just coffee" },
     { _id: 4, name: "Clothes Clothes Clothes", description: "Discount clothing" },
     { _id: 5, name: "Java Shopping", description: "Indonesian goods" },
     { _id: 6, name: "Java Hut", description: "Coffee and cakes" }
   ]
)

索引

db.stores.createIndex( { name: "text" } )

现在,如果我查询

db.stores.find({
    $text: {
        $search: "Java Shop"
    }
}, {
    score: {
        $meta: "textScore"
    }
}).sort({
    score: {
        $meta: "textScore"
    },
    _id: -1
})

它将匹配令牌并且结果为

/* 1 */
{
    "_id" : 6.0,
    "name" : "Java Shopping",
    "description" : "Indonesian goods",
    "score" : 1.5
}

/* 2 */
{
    "_id" : 5.0,
    "name" : "Java Shopping",
    "description" : "Indonesian goods",
    "score" : 1.5
}

/* 3 */
{
    "_id" : 3.0,
    "name" : "Java Coffee Shop",
    "description" : "Just coffee",
    "score" : 1.33333333333333
}

/* 4 */
{
    "_id" : 1.0,
    "name" : "Java Hut",
    "description" : "Coffee and cakes",
    "score" : 0.75
}

在这里您可以看到前三个文档与所有标记匹配,这就是为什么score大于1,而最后一个文档score小于1的原因,因为它仅匹配一个标记。

现在,在分数大于1的情况下,您还可以获得与所有令牌匹配的最佳文档。为此,我们需要使用MongoDB Aggregation。

db.stores.aggregate([
  { 
      "$match": { 
             "$text": { 
                   "$search": "Java Shop" 
              } 
       } 
  },
  { 
       "$addFields": { 
             "score": { 
                   "$meta": "textScore" 
              } 
        } 
   },
   { 
        "$match": { 
              "score": { "$gt": 1.0 } 
         } 
   },
   { 
        "$sort": { 
              "score": -1, _id: -1 
         }
   },
   { 
        "$limit": 1
   }
])

&这是结果

/* 1 */
{
    "_id" : 6.0,
    "name" : "Java Shopping",
    "description" : "Indonesian goods",
    "score" : 1.5
}