2017-02-26 32 views
13

前比方说,我有一个蒙戈集合与text indexitemName场与这3个文件:

{ 
    _id: ..., 
    itemName: 'Mashed carrots with big carrot pieces', 
    price: 1.29 
}, 
{ 
    _id: ..., 
    itemName: 'Carrot juice', 
    price: 0.79 
}, 
{ 
    _id: ..., 
    itemName: 'Apple juice', 
    price: 1.49 
} 

然后我Exec中查询,像这样:

db.items.find({ $text: { $search: 'Car' } }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } }); 

如何强制蒙戈以与“汽车”(不区分大小写)开始返回文件之前返回任何其他文档还包含“汽车”一些在itemName字符串中哪里?

所以我要检索的文档按以下顺序:

[ 
    {..., itemName: 'Carrot Juice', ...}, 
    {..., itemName: 'Mashed carrots with big carrot pieces', ...} 
] 

当然,这是指在一个搜索功能,不仅可以使用,所以它非常有意义,显示项目开始与用户之前显示任何其他项目之前他的搜索字符串。

到目前为止我使用的是标准正则表达式,但是这里的性能当然要差很多! +因为我必须搜索不区分大小写,根据文档,正常的正则表达式根本不使用任何索引?!

编辑:

而且,有时$text行为是非常奇怪的。 例如,我有大约10-15件商品,其中itemName以“Zwiebel”开头。 该查询

db.items.find({ $text: { $search: "Zwiebel" }, supplier_id: 'iNTJHEf5YgBPicTrJ' }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } }); 

的作品就像一个魅力并返回所有这些文件,而这个查询

db.items.find({ $text: { $search: "Zwie" }, supplier_id: 'iNTJHEf5YgBPicTrJ' }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } }); 

不返回任何!只有在$search中将“Zwiebel”更改为“Zwie”。

我真的不明白这怎么可能?!

最好,P

+0

它,当你排序的textScore有什么影响? –

+0

请检查我的编辑! :-) 谢谢! –

+0

@PatrickDaVader看到我的编辑 – felix

回答

7

一种解决方案是使用$indexOfCP操作者在introcuced MongoDB的3。4

这个操作符返回一个字符串的发生指数在另一个字符串,和-1如果没有occurence

它是如何工作的:

  1. 过滤掉不包含的所有文件“汽车”有一个正则表达式:/car/gi(情况inensitive)
  2. 创建一个名为index存储“车”的itemName
  3. 排序文件索引的场场

查询将是这样的:

db.items.aggregate([ 
    { 
     $match:{ 
     itemName:/car/gi 
     } 
    }, 
    { 
     $project:{ 
     index:{ 
      $indexOfCP:[ 
       { 
        $toLower:"$itemName" 
       }, 
       "car" 
      ] 
     }, 
     price:1, 
     itemName:1 
     } 
    }, 
    { 
     $sort:{ 
     index:1 
     } 
    } 
]) 

,这将返回:

{ "_id" : 2, "itemName" : "Carrot juice", "price" : 0.79, "index" : 0 } 
{ "_id" : 1, "itemName" : "Mashed carrots with big carrot pieces", "price" : 1.29, "index" : 7 } 

编辑:

对于$text指数的行为,这是完全正常的

使用定界符(默认分隔符是空格和标点)的文本索引标记化文本。它只能用于搜索整个世界,因此它不会对词

的分部从mongodb text index documentation

$文本的工作将使用空格和最 标点符号作为分隔符标记化的搜索字符串,并在搜索字符串执行逻辑或全部令牌 。

+0

感谢您的回复!请检查我在OP中的编辑!谢谢! –