美文网首页我爱编程
[原创] Java实现MongoDB数据导入及自定义复杂查询函数

[原创] Java实现MongoDB数据导入及自定义复杂查询函数

作者: 三万_chenbing | 来源:发表于2018-01-24 14:41 被阅读0次

    本实验主要包含三部分:

    1、从源文件中加载数据至数据库中。

    2、从数据库中查询数据验证加载是否完成。

    3、自定义特定的查询函数。

    这么看,Java也是支持Mongo中的原生语法,不赖!对比Python来说,代码量稍多了些,

    毕竟一个是弱类型、非防御式编程,一个是强类型、防御式编程,Java毕竟不擅长用来编写脚本。

    测试数据:

    wubiao,chinese,91

    wubiao,math,11

    zhangsan,english,40

    zhangsan,politics,95

    zhangsan,physics,84

    lisi,computer,92

    lisi,english,95

    lisi,chinese,88

    wanger,mathematics,90

    wanger,english,60

    wanger,chinese,40

    zhaoliu,economics,96

    zhaoliu,computer,94

    复制代码

    计划数据库中存储数据结构为:

    { "course" : "chinese", "score" : 91, "name" : "wubiao" }

    { "course" : "math", "score" : 11, "name" : "wubiao" }

    { "course" : "english", "score" : 40, "name" : "zhangsan" }

    { "course" : "politics", "score" : 95, "name" : "zhangsan" }

    { "course" : "physics", "score" : 84, "name" : "zhangsan" }

    { "course" : "computer", "score" : 92, "name" : "lisi" }

    { "course" : "english", "score" : 95, "name" : "lisi" }

    { "course" : "chinese", "score" : 88, "name" : "lisi" }

    { "course" : "mathematics", "score" : 90, "name" : "wanger" }

    { "course" : "english", "score" : 60, "name" : "wanger" }

    { "course" : "chinese", "score" : 40, "name" : "wanger" }

    { "course" : "economics", "score" : 96, "name" : "zhaoliu" }

    { "course" : "computer", "score" : 94, "name" : "zhaoliu" }

    复制代码

    源文件每行数据包含姓名、课程、得分,以逗号分隔。对于这几条数据来说,完全可以用Mongo客户端手段插入,

    但是如果几十万条,几百万条呢?不可能一行一行自己插,所以必须要借助工具或脚本实现。

    本次查找的需求是:找出有至少两门课程成绩达到90以上的学员名单。这只是个很简单的需求,其实我们完全可以很轻松的自定义各种复杂的查询函数。

    环境:

    OS:CentOS 5.9 32bit

    JDK:jdk1.6.0_29

    MongoDB: 2.2.3

    driver:mongo-2.10.1.jar

    如果MongoDB还没安装配置好,可以参考:

    CentOS下使用yum安装MongoDB及相关配置http://f.dataguru.cn/forum.php?mod=viewthread&tid=56377&fromuid=4771

    如果不了解MongoDB的java驱动可以参考:

    JAVA操作MongoDB--mongodb/mongo-java-driver

    http://f.dataguru.cn/forum.php?mod=viewthread&tid=94472&fromuid=4771

    OK,开搞。。

    先启动mongod

    [root@biao ~]# mongod -f /etc/mongod.conf

    all output going to: /mongodb/log/mongodb.log

    forked process: 32465

    child process started successfully, parent exiting

    [root@biao ~]# service mongod status

    mongod (pid 32465) is running...

    [root@biao ~]# ps aux|grep mongod

    root     32465  0.6  0.7 118388 22008 ?        Sl   02:00   0:00 mongod -f /etc/mongod.conf

    root     32559  0.0  0.0   4032   684 pts/11   R+   02:01   0:00 grep mongod

    [root@biao ~]# netstat -aux|grep mongod

    unix  2      [ ACC ]     STREAM     LISTENING     519024 /tmp/mongodb-27017.sock

    复制代码

    如上所示,mongod启动成功,监听端口为27017。

    Java代码:

    package com.wubiao.mongo;

    import java.io.BufferedReader;

    import java.io.File;

    import java.io.FileNotFoundException;

    import java.io.FileReader;

    import java.io.IOException;

    import java.net.UnknownHostException;

    import java.util.ArrayList;

    import java.util.Iterator;

    import java.util.List;

    import com.mongodb.BasicDBObject;

    import com.mongodb.DB;

    import com.mongodb.DBCollection;

    import com.mongodb.DBCursor;

    import com.mongodb.DBObject;

    import com.mongodb.MongoClient;

    public class Test {

    public static void main(String[] args) {

    Test test = new Test();

    DBCollection dbCollection = null;

    try {

    dbCollection = test.getCollection(null, "test_java", "stu");

    } catch (UnknownHostException e) {

    e.printStackTrace();

    }

    // 源文件路径为/root/Desktop/data.txt

    String separator = File.separator;

    File file = new File(separator + "root" + separator + "Desktop" + separator + "data.txt");

    //加载数据,并返回成功加载的行数

    test.loadData(file, dbCollection);

    //打印所有文档

    test.printAllDocs(dbCollection);

    //查找至少两门课成绩达到90以上的同学名单

    test.findNameByTwoScore(dbCollection);

    }

    /**

    * 获取要操作的集合

    * @param mongoClient

    * @param database

    * @param collection

    * @return

    * @throws UnknownHostException

    */

    public DBCollection getCollection(MongoClient mongoClient, String database, String collection) throws UnknownHostException {

    if (mongoClient == null) {

    //建立连接

    mongoClient = new MongoClient();

    }

    //获取数据库

    DB db = mongoClient.getDB(database);

    //获取集合

    DBCollection dbCollection = db.getCollection(collection);

    return dbCollection;

    }

    /**

    * 从源文件中加载数据至数据库中

    * @param file 源数据文件

    * @param dbCollection 要加载至的集合

    * @return 返回成功加载的行数,也就是文档数

    */

    public int loadData(File file,DBCollection dbCollection) {

    if (file == null || !file.isFile() || !file.exists()) {

    return 0;

    }

    BufferedReader reader = null;

    ArrayList docs = new ArrayList();

    try {

    reader = new BufferedReader(new FileReader(file));

    String line = null;

    System.out.println("***下列行将会作为文档被插入至数据库中...***");

    while ((line = reader.readLine()) != null) {

    System.out.println(line);

    String[] lines = line.split(",");

    BasicDBObject doc = new BasicDBObject();

    doc.append("name", lines[0]);

    doc.append("course", lines[1]);

    doc.append("score", Integer.valueOf(lines[2]));

    docs.add(doc);

    }

    if (docs.size() > 0) {

    dbCollection.insert(docs);

    }

    } catch (FileNotFoundException e) {

    e.printStackTrace();

    } catch (IOException e) {

    e.printStackTrace();

    } finally {

    if (reader != null) {

    try {

    reader.close();

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    }

    System.out.println("***总计有" + docs.size() + "行作为文档已被插入数据库中...***");

    return docs.size();

    }

    /**

    * 打印集合中包含的所有文档

    * @param dbCollection 要查询的集合

    */

    public static void printAllDocs(DBCollection dbCollection) {

    //获取当前集合中所有对象的游标

    DBCursor dbCursor = dbCollection.find();

    //迭代打印所有对象

    System.out.println("****当前集合包含的所有文档 begin****");

    while (dbCursor.hasNext()) {

    System.out.println("* " + dbCursor.next());

    }

    System.out.println("****当前集合包含的所有文档 end******");

    }

    /**

    * 在集合中查询至少两门课程成绩大于90的学员

    * @param dbCollection 要查询的集合

    * @return 查询符合条件的学员姓名

    */

    public List findNameByTwoScore(DBCollection dbCollection) {

    //获取所有学员的姓名

    ArrayList AllNames = (ArrayList) dbCollection.distinct("name");

    //要返回的学员姓名列表

    ArrayList names = new ArrayList();

    //迭代学员姓名,按学员姓名与成绩大于90作为查询条件

    //当查询所得的结果大于等于2时,表示符合查询,返回

    for (Iterator iter = AllNames.iterator(); iter.hasNext(); ) {

    String name = iter.next();

    DBCursor cursor = dbCollection.find(new BasicDBObject("name",name).append("score", new BasicDBObject("$gt",90)));

    if (cursor.count() > 1) {

    names.add(name);

    }

    }

    System.out.println("***至少两门课成绩达到90以上的同学名单:");

    System.out.println(names);

    return names;

    }

    }

    /*

    控制台打印信息:

    ***下列行将会作为文档被插入至数据库中...***

    wubiao,chinese,91

    wubiao,math,11

    zhangsan,english,40

    zhangsan,politics,95

    zhangsan,physics,84

    lisi,computer,92

    lisi,english,95

    lisi,chinese,88

    wanger,mathematics,90

    wanger,english,60

    wanger,chinese,40

    zhaoliu,economics,96

    zhaoliu,computer,94

    ***总计有13行作为文档已被插入数据库中...***

    ****当前集合包含的所有文档 begin****

    * { "_id" : { "$oid" : "5167513de4b0619e77863b43"} , "name" : "wubiao" , "course" : "chinese" , "score" : 91}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b44"} , "name" : "wubiao" , "course" : "math" , "score" : 11}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b45"} , "name" : "zhangsan" , "course" : "english" , "score" : 40}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b46"} , "name" : "zhangsan" , "course" : "politics" , "score" : 95}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b47"} , "name" : "zhangsan" , "course" : "physics" , "score" : 84}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b48"} , "name" : "lisi" , "course" : "computer" , "score" : 92}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b49"} , "name" : "lisi" , "course" : "english" , "score" : 95}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b4a"} , "name" : "lisi" , "course" : "chinese" , "score" : 88}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b4b"} , "name" : "wanger" , "course" : "mathematics" , "score" : 90}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b4c"} , "name" : "wanger" , "course" : "english" , "score" : 60}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b4d"} , "name" : "wanger" , "course" : "chinese" , "score" : 40}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b4e"} , "name" : "zhaoliu" , "course" : "economics" , "score" : 96}

    * { "_id" : { "$oid" : "5167513de4b0619e77863b4f"} , "name" : "zhaoliu" , "course" : "computer" , "score" : 94}

    ****当前集合包含的所有文档 end******

    ***至少两门课成绩达到90以上的同学名单:

    [lisi, zhaoliu]

    */

    复制代码

    依然照顾到有些童鞋可能不太熟悉Java,依然尝试着在代码中加入了很详细的注释,依然应该很详细了。

    代码除了连接、获取数据库、获取集合之外,包含三部分:

    1、从源文件中加载数据至数据库中。

    2、查询所有的文档验证导入的数据。

    3、实现自定义查询。

    这三部分是相对独立的,分别有Test类中的三个方法实现,具体哪个方法执行哪些工作不用解释了,方法名就看得出来。

    三个方法可以一起执行,也可以分别执行,不想执行的部分在main方法中注释掉就好了,用双斜杠//注释即可。

    一改以往的作风,这次稍稍的封装了下,谁叫咱是喜欢面向对象的码农呢。。。

    相关文章

      网友评论

        本文标题:[原创] Java实现MongoDB数据导入及自定义复杂查询函数

        本文链接:https://www.haomeiwen.com/subject/ybdeaxtx.html