2015-06-19 29 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秒] –

相關問題