Java实现原生MongoDB的分组查询(非SpringBoot)

今天总算是将Nosql的实验搞定了,这几天网上查了很多关于MongoDB的查询,但要么是在命令行中的查询,要么是SpringBoot封装好的查询语句,对于我这种用java swing“应付”一下实验的人来说完全是远水解不了近渴。在我孜孜不倦地搜索之下,终于“拼凑”出来了,代码附在下面。

题目要求:
自选高级程序设计语言,自行设计界面,完成以下数据统计并将统计信息进行展示。
1、选择你关注的一个城市,按照“city”、“户型(types)”和“整租/合租
(lease_mode)”三个属性,展示房租的均价、中位数、最高价、最低价;
2、选择你关注的一个城市,展示出租房屋数量与月份的关系:按照房屋
“maintain”和“city”两个属性进行统计。

MongoDB类

import com.mongodb.*;
import com.mongodb.MongoClient;
import com.mongodb.client.*;
import org.bson.Document;
public class MongoDB {
    public static MongoClient mongoClient;
    static {
        MongoClientURI uri = new MongoClientURI("mongodb://用户名:密码@弹性ip:端口/admin");
        mongoClient = new MongoClient(uri);
    }

    public static MongoDatabase getDB(String dbName) {
        if (dbName != null && !"".equals(dbName)) {
            MongoDatabase database = mongoClient.getDatabase(dbName);
            return database;
        }
        return null;
    }
    
}

实现类

import com.mongodb.BasicDBObject;
import com.mongodb.client.AggregateIterable;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Accumulators;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import org.bson.Document;
import org.bson.conversions.Bson;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Vector;

public class test extends JFrame implements ActionListener {
    private JLabel CityLabel;//
    private JComboBox<String> c1;
    private Box cityBox;
    private Box TableBox;
    private Box MonthBox;
    private JScrollPane MonthscrollPane =null;
    private DefaultTableModel MonthtableModel=null;
    private JTable Monthtable=null;
    private JScrollPane scrollPane = null;
    private DefaultTableModel tableModel = null;
    private JTable table = null;
    private JButton select_1;
    private JButton select_2;

    public test(){
        //实例化所有的对象
        CityLabel =new JLabel("城市");

        select_1 = new JButton("第一问查询");
        select_1.addActionListener(this);
        select_2 = new JButton("第二问查询");
        select_2.addActionListener(this);
        //制作下拉框
        c1 = new JComboBox<String>();
        c1.addItem("北京");
        c1.addItem("杭州");
        c1.addItem("广州");
        c1.addItem("济南");
        c1.addItem("南京");
        c1.addItem("上海");
        c1.addItem("深圳");
        c1.addItem("西安");
        cityBox=Box.createHorizontalBox();//内部组件,水平排列
        TableBox=Box.createHorizontalBox();//内部组件,水平排列
        MonthBox=Box.createHorizontalBox();//内部组件,水平排列
        //初始化表格
        //一维数组  表格标题
        String[] title = new String[] {"city","types","mode","均价","中位数","最高价","最低价"};
        //二维数组 表格中数据
        String[][] data = new String[0][];
        this.tableModel = new DefaultTableModel(data, title);
        this.table = new JTable(this.tableModel);
        this.scrollPane = new JScrollPane(table);
        TableBox.add(this.scrollPane);
        //初始化月份表格
        String[] month_title = new String[] {"城市","月份","数量"};
        String[][] month_data = new String[0][];
        this.MonthtableModel = new DefaultTableModel(month_data, month_title);
        this.Monthtable = new JTable(this.MonthtableModel);
        this.MonthscrollPane = new JScrollPane(Monthtable);
        MonthBox.add(this.MonthscrollPane);
        //将相关内容加入盒子
        cityBox.add(CityLabel);
        cityBox.add(Box.createHorizontalStrut(10));//输入框与label的横向间隔
        cityBox.add(c1);

        setLayout(null);
        setBounds(50,50,1000,1000);//该窗口本身的位置和大小
        //加入Box
        add(cityBox);
        add(TableBox);
        add(MonthBox);
        add(select_1);
        add(select_2);
        select_1.setBounds(60,140,100,50);
        select_2.setBounds(60,500,100,50);
        cityBox.setBounds(20,20,200,100);
        TableBox.setBounds(20,200,500,300);
        MonthBox.setBounds(20,550,500,300);
        setVisible(true);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        validate();

    }
    public void actionPerformed(ActionEvent e){
        if(e.getSource()==select_1){
          String city = c1.getSelectedItem().toString();
            Vector data = new Vector(); // 数据行向量集,因为列表不止一行,往里面添加数据行向量,添加方法add(row)
        Vector names = new Vector();// 列名向量,使用它的add()方法添加列名
            names.add("城市");
            names.add("户型");
            names.add("整租/合租");
            names.add("平均值");
            names.add("中位数");
            names.add("最大值");
            names.add("最小值");
            MongoDatabase mongoDatabase = MongoDB.getDB("你的数据库名");
            MongoCollection<Document> collection = mongoDatabase.getCollection("rent");
            Document groupFields  = new Document("types", "$base_info.types").append("lease_mode", "$lease_mode");
            AggregateIterable<Document> aggregate = collection.aggregate(Arrays.asList(
                    Aggregates.match(Filters.eq("city",city)),
                    Aggregates.group(groupFields,Accumulators.sum("sum",1),Accumulators.avg("avg","$price"),Accumulators.max("max","$price"),Accumulators.min("min","$price"))
            ));

            for (Document document: aggregate){
                int median = 0;
                int total_number = (int) document.get("sum");
                Document d = (Document) document.get("_id");
                BasicDBObject basicDBObject=new BasicDBObject();
                basicDBObject.put("city",city);
                basicDBObject.append("base_info.types",d.get("types"));
                basicDBObject.append("lease_mode",d.get("lease_mode"));
                BasicDBObject dbObject=new BasicDBObject();
                dbObject.put("price",1);
                FindIterable<Document> iterable;
                if (total_number % 2 == 0) {
                    if((total_number/2-1)<=0){
                        iterable = collection.find(basicDBObject).sort(dbObject);
                    }
                    else {
                        iterable = collection.find(basicDBObject).sort(dbObject).limit(2).skip(total_number/2-1);
                    }
                    for (Document document1 : iterable){
                        median+=(int)document1.get("price");
                    }
                    median=median/2;
                }
                else{
                    int middle_number= (int) (total_number/2+0.5);
                    iterable = collection.find(basicDBObject).sort(dbObject).limit(1).skip(middle_number-1);
                }
                for (Document document1 : iterable){
                    median= (int) document1.get("price");
                }

                Vector row = new Vector();
                row.add(city);
                row.add(d.get("types"));
                row.add(d.get("lease_mode"));
                row.add(document.get("avg"));
                row.add(median);
                row.add(document.get("max"));
                row.add(document.get("min"));
                data.add(row);
            }
            tableModel.setDataVector(data, names);

        }
        else if(e.getSource()==select_2){
            //实验第二问
            String city = c1.getSelectedItem().toString();
            Vector month_data = new Vector(); // 数据行向量集,因为列表不止一行,往里面添加数据行向量,添加方法add(row)
            Vector month_names = new Vector();// 列名向量,使用它的add()方法添加列名
            month_names.add("城市");month_names.add("月份");month_names.add("数量");
            BasicDBObject basicDBObject=new BasicDBObject();
            basicDBObject.put("city",city);
            MongoDatabase mongoDatabase = MongoDB.getDB("你的数据库名");
            MongoCollection<Document> collection = mongoDatabase.getCollection("rent");
            FindIterable<Document> findIterable=collection.find(basicDBObject);
            int[] months = new int[12];
            for (Document document: findIterable) {
                Document d = (Document) document.get("base_info");
                String str = d.get("maintain").toString();
                String month=str.substring(4,7);
                //这个地方需要用月份的缩写
                switch (month){
                    case "Jan":
                        months[0]++;
                        break;
                    case "Feb":
                        months[1]++;
                        break;
                    case "Mar":
                        months[2]++;
                        break;
                    case "Apr":
                        months[3]++;
                        break;
                    case "May":
                        months[4]++;
                        break;
                    case "Jun":
                        months[5]++;
                        break;
                    case "Jul":
                        months[6]++;
                        break;
                    case "Aug":
                        months[7]++;
                        break;
                    case "Sep":
                        months[8]++;
                        break;
                    case "Oct":
                        months[9]++;
                        break;
                    case "Nov":
                        months[10]++;
                        break;
                    case "Dec":
                        months[11]++;
                        break;
                }

            }
            String[] months_name={"January","February","Match", "April","May","June","July","August","September","October","November","December"};
            for(int i=0;i<12;i++){
                Vector row = new Vector();
                row.add(city);
                row.add(months_name[i]);
                row.add(months[i]);
                month_data.add(row);
            }
            MonthtableModel.setDataVector(month_data, month_names);
        }
    }
    public static void main(String[] args) {
        new test();
    }
}

结果展示:(没时间美化界面了,能看就行)
在这里插入图片描述
不知道是因为数据多还是方法选择的问题,查询的速度较慢,希望能解决这个问题,如果读者有更好的方法可以评论一起探讨。
如果需要源码以及数据的话,可以私信我,我发给你。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值