問題:集合stu存放一所高等學校的學生選修成績,包括學號以及各科(科目每人可能都不相同,沒法固定),寫出查詢語句,找出有至少兩門課達到90以上的同窗名單mongodb
首先須要有一個測試的數據集......我找到一個成績的數據文件是:「東北林業大學2012年六月四六級成績單(包含全校的成績及其餘語種).xls」,數據下載地址在這裏ruby
這個文檔中的數據太多了,我只截取了其中幾列,分別是課程,學號,成績,示例數據以下測試
日語四級 092011050201668 0 日語四級 092011050201678 0 日語四級 1010110502010819 71 日語四級 1010110502010814 53.5 英語六級 20080027 0 英語六級 20080040 0 英語六級 20080017 303 英語六級 20080029 0 英語六級 20080037 0
整理後的數據下載在這裏,數據總共14510行,而後須要將數據插入到mongodb中,使用以下ruby腳本ui
#!/usr/bin/env ruby #encoding:utf-8 # 20140301, load_score.rb ### ### require "rubygems" require "mongo" class LoadScore def initialize(host, port) @mongoconn = Mongo::MongoClient.new(host, port) @db = @mongoconn.db("test") @coll = @db.collection("stu") end def insert_score(user_id, course, score) @coll.update({ "user_id" => user_id }, {"$set" => {"#{course}"=>score}}, :upsert=>true, :multi=>false) end def clear_score() @db.drop_collection("stu") end def pf() p @coll.find.to_a end end mongo_conn = LoadScore.new("localhost", 27017) File.open("scores.txt") do |f| while (line = f.gets) word = line.split(" ") mongo_conn.insert_score(word[1], word[0], word[2].to_f) end end # mongo_conn.pf() # mongo_conn.clear_score()
這個數據集分數分佈很不平均,並且俄語、法語、英語都有,滿分也不同。實驗中我是查有2門達到50分的學生(實際上,有2門課成績的總共只有16人),查詢語句以下this
db.stu.find({"$where" : function (){ cnt = 0; for (var key in this){ if (key!="_id" && key!="user_id" && this[key] >= 50){ cnt = cnt +1 } } if (cnt >= 2){ return true; }else { return false; } } }, {_id:0} )
結果集有5條數據url
{ "俄語六級" : 55, "俄語四級" : 61, "user_id" : "20101647" } { "俄語六級" : 57, "俄語四級" : 78.5, "user_id" : "20101356" } { "俄語六級" : 71.5, "俄語四級" : 81, "user_id" : "20111083" } { "俄語六級" : 55, "俄語四級" : 78, "user_id" : "20113628" } { "俄語六級" : 56.5, "俄語四級" : 72.5, "user_id" : "1110051202021049" }
彷佛簡單的不用「$where」的寫法不能處理這個問題,固然,這個跟集合的設計也有關係。spa