3

我正在寻找微调我在 Mongo 上使用的字符串搜索查询。在 SQL Server 世界中,我相信我对索引的工作原理以及如何构建正确的索引有相当的了解。我试着用 Mongo 试一试,但是,我不相信我不会以正确的方式去做。

我的收藏大约有 430 万份文档。文档结构如下所示:

{
   "_id":{
      "$oid":"527027456239d1212c07a621"
   },
   "ReleaseId":2451,
   "Status":"Accepted",
   "Title":"Hard Rhythmic Motions",
   "Country":"US",
   "MasterId":"35976",
   "Images":[
      {
         "Type":"primary",
         "URI":"http://api.discogs.com/image/R-2451-1117047026.jpg",
         "URI150":"http://api.discogs.com/image/R-150-2451-1117047026.jpg",
         "Height":307,
         "Width":307
      },
      {
         "Type":"secondary",
         "URI":"http://api.discogs.com/image/R-2451-1117047033.jpg",
         "URI150":"http://api.discogs.com/image/R-150-2451-1117047033.jpg",
         "Height":307,
         "Width":307
      }
   ],
   "Artists":[
      {
         "_id":2894,
         "Name":"DJ Hyperactive"
      }
   ],
   "Formats":[
      {
         "Name":null,
         "Quantity":1
      }
   ],
   "Genres":[
      "Electronic"
   ],
   "Styles":[
      "Hardcore",
      "Acid"
   ]
}

我正在对顶级文档属性之一和嵌套文档属性之一执行不区分大小写的搜索:

db.releases.find({$or: [{Title: new RegExp('.*mozart.*',"i")},{'Artists.Name': new RegExp('.*mozart.*',"i")}]})

我尝试创建一个索引;当我执行时,.getIndexes()我可以看到我创建的索引:

{
    "v" : 1,
    "key" : {
            "Title" : 1,
            "Artists.Name" : 1
    },
    "ns" : "discogs.releases",
    "name" : "Title_1_Artists.Name_1"
}

在这一点上,我认为我会准备好。但是,查询最终需要 28 到 32 秒才能执行。我试着打电话.explain()以获得更多的见解:

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 4098,
    "nscannedObjects" : 4292400,
    "nscanned" : 4292400,
    "nscannedObjectsAllPlans" : 4292400,
    "nscannedAllPlans" : 4292400,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 29,
    "nChunkSkips" : 0,
    "millis" : 29958,
    "indexBounds" : {

    },
    "server" : "lambic:27017"
}

从我对 Mongo 的有限了解来看,这看起来像是一个表扫描,这就是查询执行得不是很好的原因。但是,我不知道如何使这个查询更好!我希望我创建的索引可以覆盖这个查询,但是,情况一定不是这样。

现在,我要指出的最后一件事是,这肯定不是在最强大的服务器上。硬件规格(包括 CPU 和 RAM)非常有限。但是,如果我的分析是正确的并且我正在执行表扫描,那么我可以在 Mongo 方面进行一些性能改进。

4

2 回答 2

0

全文索引可能是您所需要的。您还可以在插入文档之前对其进行解析,并将关键字放在文档内的数组中并索引该数组。

于 2013-11-15T08:28:41.697 回答
0

感谢大家的回复。我想跟进这个问题,因为它有几票,并确保将来偶然发现此页面的任何人都知道我最终做了什么。

全文索引听起来是一个很好的解决方案。然而,因为这只是我的一个小项目,我不愿意在架构上投入更多的硬件(全文索引需要大量的磁盘空间来存储 400 万条记录)。

我最终做的是扁平化我的数据结构以使它们更易于查询删除通配符搜索,以便我可以实际使用该新结构上的索引。通过这样做,我可以实现 indexOnly 查询(尽管性能仍然不理想,但鉴于我的硬件堆栈较弱,我发现它已经足够了)。

于 2013-11-27T17:36:41.927 回答