问题:集合stu存放一所高等学校的学生选修成绩,包括学号以及各科(科目每人可能都不相同,无法固定),写出查询语句,找出有至少两门课达到90以上的同学名单
首先需要有一个测试的数据集......我找到一个成绩的数据文件是:“东北林业大学2012年六月四六级成绩单(包含全校的成绩及其他语种).xls”,数据下载地址在这里
这个文档中的数据太多了,我只截取了其中几列,分别是课程,学号,成绩,示例数据如下
日语四级 092011050201668 0 日语四级 092011050201678 0 日语四级 1010110502010819 71 日语四级 1010110502010814 53.5 英语六级 20080027 0 英语六级 20080040 0 英语六级 20080017 303 英语六级 20080029 0 英语六级 20080037 0
整理后的数据下载在这里,数据总共14510行,然后需要将数据插入到mongodb中,使用如下ruby脚本
#!/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人),查询语句如下
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条数据
{ "俄语六级" : 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”的写法不能处理这个问题,当然,这个跟集合的设计也有关系。