我有不同字段的电影数据库。类型字段包含一个逗号分隔的字符串,如:如何在mongodb中搜索逗号分隔的数据
{genre: 'Action, Adventure, Sci-Fi'}
我知道我可以使用正则表达式来查找匹配。我也试过:
{'genre': {'$in': genre}}
问题是运行时间。它会花费很多时间来返回查询结果。该数据库有大约300K文件,并且我已经对'流派'字段进行了正常索引。
我有不同字段的电影数据库。类型字段包含一个逗号分隔的字符串,如:如何在mongodb中搜索逗号分隔的数据
{genre: 'Action, Adventure, Sci-Fi'}
我知道我可以使用正则表达式来查找匹配。我也试过:
{'genre': {'$in': genre}}
问题是运行时间。它会花费很多时间来返回查询结果。该数据库有大约300K文件,并且我已经对'流派'字段进行了正常索引。
会说使用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"
]
}
那么你不能真正做到这一点有效,所以我很高兴你用你的问题标签“表演”。
如果你想与做这个字符串中的“逗号分隔”数据的地方,你需要这样做:
无论是与一般的正则表达式,如果它适合:
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" })
当你这样做的时候就是这么简单。而确实是高效。
您做出选择。
我实现了Map-Reduce方法。这里是结果: [记录在分贝:289705] [添加新的集合,只有流派:25.2529330254秒] [地图/减少操作:27.657秒] [创建索引:3秒] [每个查询:0.311秒] –
也贪婪匹配“*”是非常昂贵的一个不必要的。 – 2015-06-19 15:21:30