MONGODB全文搜索逻辑或查询

时间:2016-01-14 16:31:31

标签: mongodb indexing full-text-search nosql

我目前正在开发一个项目,需要在1000毫秒内搜索(在本地计算机上)大型数据库(+25.000.000条记录)。这让我想到了MongoDB,可以达到理想的性能。我可以通过几种不同的索引来做到这一点,但是我需要能够部分匹配。

允许最终用户搜索几个字段。 (并非所有字段;需要能够搜索5/9的字段,其余的是无法为最终用户搜索的元数据

我首先尝试为全文搜索创建复合索引(在所有5个字段上)

db.tracks.find({$text:{$search:"Greatest Hits"}})

这似乎运作得相当好,并且在任何复合领域给出了各种各样的结果,包括Great,Greatest和Hits。

但是,用户应该能够选择他想要搜索的字段。 (例如:AlbumTitle,TrackTitle等)。这意味着当切换曲目标题时,我不想要该列的结果。

db.tracks.find({AlbumTitle: "Greatest Hits"})

上面的查询将能够找到完全匹配,因此在搜索Greatest时找不到相同的结果。这让我想到了类似下面的内容

db.tracks.find({AlbumTitle: {$text: {$search: "Greatest Hits"}}})

但这并不起作用,因为那时$ text将是一个未知的运算符。

如果有类似上述内容的话,我可以根据切换字段动态构建我的查询,例如

db.tracks.find({$or: [ {ToggledField1: ...}, {ToggeldField4: ...}  ]})

因此确保仅查询所需的字段。在MongoDB数据库中是否可以实现这一点,如果是这样,实现所需功能的最佳方法是什么

先谢谢

1 个答案:

答案 0 :(得分:0)

最后我解决了它,如下所示

// Create an empty filter and make sure it is not null
var builder = Builders<Track>.Filter;
FilterDefinition<Track> filter = builder.Empty;

string[] searchWords = queryString.Split(' ');
if (ArtistChecked){
  foreach (var words in searchWords){
   //regex could be changed with options like ignore case
   filter &= builder.Regex("Artist", BsonRegularExpression.Create(new System.Text.RegularExpressions.Regex(word)));
  }
}
if (AlbumChecked){
  foreach (var words in searchWords){
   //regex could be changed with options like ignore case
   filter &= builder.Regex("Album", BsonRegularExpression.Create(new System.Text.RegularExpressions.Regex(word)));
  }
}

最后,您在MongoQuery中使用构建过滤器;可以在OR运算符中混合使用EQ来查询查询中的某些字段;但这样你就可以动态地构建查询。 当然,性能不如完全匹配(使用FullTextSearch),但这将使搜索方法变得可用。通过使用索引并说它以前缀

开头,性能可能更好
  

如果该字段存在索引,则MongoDB会将正则表达式与索引中的值进行匹配,这可能比收集扫描更快。如果正则表达式是“前缀表达式”,则可以进一步优化,这意味着所有可能的匹配都以相同的字符串开头。这允许MongoDB从该前缀构造一个“范围”,并且仅匹配该范围内的索引中的那些值。

来源:https://docs.mongodb.org/manual/reference/operator/query/regex/#index-use

在我的情况下,这不会做,因为用户应该能够以他们想要的任何顺序输入搜索词;因为它只是出现在字段内部,所以无法保证使用正确的顺序。

打开以获取有关如何更快/更好的建议

P.S。有想法从MongoDB substring product search order by highest match

解决它