mongodb导入非结构化数据并查询

问题:集合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”的写法不能处理这个问题,当然,这个跟集合的设计也有关系。

posted @ 2014-03-01 19:04  valleylord  阅读(1932)  评论(0编辑  收藏  举报