我有不同字段的電影數據庫。類型字段包含一個逗號分隔的字符串,如:如何在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