2015-06-19 31 views
3

我有不同字段的电影数据库。类型字段包含一个逗号分隔的字符串,如:如何在mongodb中搜索逗号分隔的数据

{genre: 'Action, Adventure, Sci-Fi'} 

我知道我可以使用正则表达式来查找匹配。我也试过:

{'genre': {'$in': genre}} 

问题是运行时间。它会花费很多时间来返回查询结果。该数据库有大约300K文件,并且我已经对'流派'字段进行了正常索引。

回答

3

会说使用Map-Reduce创建一个单独的集合存储genre与从逗号分隔字符串,然后你就可以运行地图-Reduce作业和输出集合管理查询拆分未来值的数组。

例如,我创建了一些样本文档的foo集合:

db.foo.insert([ 
    {genre: 'Action, Adventure, Sci-Fi'}, 
    {genre: 'Thriller, Romantic'}, 
    {genre: 'Comedy, Action'} 
]) 

以下的map/reduce操作,然后将产生从中可以应用于高性能的查询集合:

map = function() { 
    var array = this.genre.split(/\s*,\s*/); 
    emit(this._id, array); 
} 

reduce = function(key, values) { 
    return values; 
} 

result = db.runCommand({ 
    "mapreduce" : "foo", 
    "map" : map, 
    "reduce" : reduce, 
    "out" : "foo_result" 
}); 

查询会很简单,利用value字段上的多键索引查询:

db.foo_result.createIndex({"value": 1}); 

var genre = ['Action', 'Adventure']; 
db.foo_result.find({'value': {'$in': genre}}) 

输出

/* 0 */ 
{ 
    "_id" : ObjectId("55842af93cab061ff5c618ce"), 
    "value" : [ 
     "Action", 
     "Adventure", 
     "Sci-Fi" 
    ] 
} 

/* 1 */ 
{ 
    "_id" : ObjectId("55842af93cab061ff5c618d0"), 
    "value" : [ 
     "Comedy", 
     "Action" 
    ] 
} 
+0

也贪婪匹配“*”是非常昂贵的一个不必要的。 – 2015-06-19 15:21:30

0

那么你不能真正做到这一点有效,所以我很高兴你用你的问题标签“表演”。

如果你想与做这个字符串中的“逗号分隔”数据的地方,你需要这样做:

无论是与一般的正则表达式,如果它适合:

db.collection.find({ "genre": { "$regex": "Sci-Fi" } }) 

但效率不高。

或者由JavaScript评价通过:

db.collection.find(function() { 
    return ( 
     this.genre.split(",") 
      .map(function(el) { 
       return el.replace(/^\s+/,"") 
      }) 
      .indexOf("Sci-Fi") != -1; 
    ) 
}) 

不是真的有效,大概等于以上。

或者更好的是什么东西,可以使用索引,单独到一个数组,并使用一个基本查询:

{ 
    "genre": [ "Action", "Adventure", "Sci-Fi" ] 
} 

随着指数:

db.collection.ensureIndex({ "genre": 1 }) 

然后查询:

db.collection.find({ "genre": "Sci-Fi" }) 

当你这样做的时候就是这么简单。而确实是高效。

您做出选择。

+0

我实现了Map-Reduce方法。这里是结果: [记录在分贝:289705] [添加新的集合,只有流派:25.2529330254秒] [地图/减少操作:27.657秒] [创建索引:3秒] [每个查询:0.311秒] –

相关问题