MongoDB + SpringBoot 的基础CRUD、聚合查询

1、数据准备

1.1、springboot导包

  • springboot版本:2.7.10
点击查看代码
        <!--mongodb的包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>

1.2、配置文件yml

点击查看代码
spring:
  data:
    mongodb:
      # 有账号密码
      uri: mongodb://账户名:密码@IP:端口/数据库
      # 无账号密码
      # uri: mongodb://IP:端口/数据库

1.3、实体类

  • 也可以不使用实体类来存数据、查询数据
点击查看代码
package com.cc.mdb.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.time.LocalDateTime;

/**
 * @Document("User") 存入的时候不取对象名,默认用User当做表名
 */
@Data
@Document("User")
public class User {

    @Id
    private String id;
    /**
     * 使用name当做字段key
     */
    @Field("name")
    private String name;
    /**
     * 使用age1当做字段key
     */
    @Field("age1")
    private Integer age;
    /**
     * 使用email当做字段key
     */
    @Field("email")
    private String email;
    /**
     * 使用createDate当做字段key
     */
    @Field("createDate")
    private LocalDateTime createDate = LocalDateTime.now();
}

2、基础CRUD

  • 参考:http://blog.csdn.net/weixin_44185213/article/details/125293170?spm=1001.2014.3001.5502
  • 注入:SpringBoot中使用 MongoTemplate 来操作MongoDB
点击查看代码
package com.cc.mdb.test;

import com.alibaba.fastjson.JSONObject;
import com.cc.mdb.BaseTest;
import com.cc.mdb.entity.User;
import com.mongodb.client.result.UpdateResult;
import org.junit.Test;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Pattern;

/** CRUD
 *  查询使用:Query
 *  博客:http://blog.csdn.net/weixin_44185213/article/details/125293170?spm=1001.2014.3001.5502
 * @author CC
 * @since 2023/3/30 0030
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestMongoQuery{

    @Resource
    private MongoTemplate mongoTemplate;

    //写入简单数据 —— 根据对象存数据
    @Test
    public void test01()throws Exception{
        List<User> vos = new ArrayList<>();
        for (int i = 10; i < 20; i++) {
            User user = new User();
            String aa = i + "" + i + "" + i + "";
            user.setId(aa);
            user.setName("cscs"+aa);
            user.setAge(123);
            user.setEmail("11@qq.com");
            vos.add(user);
        }
        Collection<User> user2 = mongoTemplate.insert(vos, "User2");
        System.out.println(user2);
    }

    //写入简单数据 —— 根据json存数据(JSONObject(Fastjson))
    @Test
    public void test02()throws Exception{
        List<JSONObject> vos = new ArrayList<>();
        for (int i = 1; i < 20; i++) {
            JSONObject result = new JSONObject();
            String aa = i + "" + i + "" + i + "";
            result.put("id",aa);
            result.put("name","cscs"+aa);
            result.put("age",123);
            result.put("email","11@qq.com");
            vos.add(result);
        }
        Collection<JSONObject> user3 = mongoTemplate.insert(vos, "User3");
        System.out.println(user3);
    }

    //写入复杂数据 —— 有子文档(json数据中有下级)
    @Test
    public void test013()throws Exception{
        List<JSONObject> vos = new ArrayList<>();
        for (int i = 1; i < 20; i++) {
            JSONObject result = new JSONObject();
            String aa = i + "" + i + "" + i + "";
            result.put("id",aa);
            result.put("name","cscs"+aa);
            result.put("age",123);
            result.put("email","11@qq.com");

            List<JSONObject> jss = new ArrayList<>();
            for (int j = 0; j < 2; j++) {
                JSONObject js = new JSONObject();
                js.put("sId",j);
                js.put("sName","学校" + aa);
                js.put("sNo","学校编号" + aa);
                js.put("sTab",1);

                List<JSONObject> whats = new ArrayList<>();
                if (i == 1){
                    for (int k = 0; k < 2; k++) {
                        JSONObject kk = new JSONObject();
                        kk.put("kId",k);
                        kk.put("kName","k"+k);
                        whats.add(kk);
                    }
                }
                js.put("sWhat",whats);
                jss.add(js);
            }
            result.put("school",jss);
            vos.add(result);
        }
        Collection<JSONObject> user3 = mongoTemplate.insert(vos, "User4");
        System.out.println(user3);
    }

    //查找全部
    @Test
    public void test03()throws Exception{
        List<User> users = mongoTemplate.findAll(User.class);
        System.out.println(users);
    }

    /** 根据json里面的字段查询
     * 查询 school.sWhat.kId 的数据
     */
    @Test
    public void test07()throws Exception{
        //查询的新增方法:test013

        Criteria cr = new Criteria();
//        cr.and("id").is("111");
//        cr.and("school.sId").is(0);
        cr.and("school.sWhat.kId").is(0);
        Query query = new Query();
        query.addCriteria(cr);

        // 执行查询并获取结果
        List<JSONObject> jsonObjects = mongoTemplate.find(query, JSONObject.class, "User4");
        System.out.println(jsonObjects);
    }

    //**高级查询:使用Query
    @Test
    public void test04()throws Exception{
        String search = "cscs";
        int page = 1;
        int size = 20;
        Query query = new Query();
        //一、where
        //1模糊
        String format = String.format("^.*%s.*$", search);
        Pattern pattern = Pattern.compile(format, Pattern.CASE_INSENSITIVE);
        Criteria criteria = Criteria.where("name").regex(pattern);
        //模糊查询方式2(推荐)
//        Criteria.where("name").regex(String.format(".*%s.*","查询的值"));

        //2等于(这里比较特殊,value:数字的必须传入数字的、字符串必须传入字符串的)
        criteria.and("age").is(123);
        query.addCriteria(criteria);

        //二、排序。按id升序
        Sort sort = Sort.by(Sort.Direction.ASC, "_id");
        query.with(sort);

        //二、总条数(是所有条件都弄了之后)
        long totalCount = mongoTemplate.count(query, JSONObject.class, "User3");

        //三、分页(必须在where和查询总条数之后)
        //方式1
//        query.skip((page - 1) * size).limit(size);
        //方式2(推荐)
        Pageable pageable = PageRequest.of(page - 1, size);
        query.with(pageable);

        //查询。由于查询出来的是key-value的形式,可以使用JSONObject(FastJson)来接收参数。如果有对象(User),可以直接使用对象来接收
        List<JSONObject> users = mongoTemplate.find(query, JSONObject.class, "User3");

        System.out.println("总条数:" + totalCount);
        System.out.println(users);
    }

    //修改 - 根据表名+id 修改其中一个json中的某些值
    @Test
    public void test05() {
        JSONObject user2 = mongoTemplate.findById("6433c76df108474b788cc4ce", JSONObject.class, "User3");
        Object id = user2.get("_id");

        Query query = new Query(Criteria.where("_id").is(id));

        Update update = new Update();
        update.set("name", "修改后的名字2");
        update.set("age", "321");
//        update.set("email", "");

        //方式1:upsert方法更新与查询条件匹配的第一个文档,如果没有文档与查询条件匹配,则插入一个新文档。
//        UpdateResult result = mongoTemplate.upsert(query, update, "User3");
//        long count = result.getModifiedCount();
//        System.out.println(count);

        //方式2:update方法更新与查询条件匹配的第一个文档
        UpdateResult user3 = mongoTemplate.updateFirst(query, update, "User3");
        //修改计数
        long modifiedCount = user3.getModifiedCount();
        System.out.println(modifiedCount);
        //匹配计数
        long matchedCount = user3.getMatchedCount();
        System.out.println(matchedCount);

        //方式3:updateMulti方法更新与查询条件匹配的所有文档。
//        UpdateResult user31 = mongoTemplate.updateMulti(query, update, "User3");
    }

    //删除 - 根据数据id删除
    @Test
    public void test06() {
        //1删除文档中的某一条数据
//        Query query = new Query(Criteria.where("_id").is("6433c76df108474b788cc4cf"));
//        DeleteResult result = mongoTemplate.remove(query, "User3");
//        long count = result.getDeletedCount();
//        System.out.println(count);

        //2删除整个文档中的数据 —— 相当于drop清空表中的数据
//        DeleteResult user4 = mongoTemplate.remove(new Query(), "User4");
//        long deletedCount = user4.getDeletedCount();
//        System.out.println(deletedCount);

        //3删除文档 —— 相当于删除表
        mongoTemplate.dropCollection("User4");
    }



}

3、聚合查询

  • 聚合意思:自己见管网

3.1、聚合查询关键字

 *      $project            指定返回字段
 *      $lookup	            多表关联
 *      $unwind	            数组拆分
 *      $match	            筛选条件
 *      $sort	            排序
 *      $limit	            分页
 *      $skip	            跳过
 *      $group	            根据id(可自定义)分组
 *      $sum	            分组后求和
 *      $first	            分组后取第一条
 *      $last	            分组后取最后一条
 *      $addToSet           分组后添加到list
 *      $cond	            可以做 if-else

3.2、聚合查询

点击查看代码
package com.cc.mdb.test;

import com.alibaba.fastjson.JSONObject;
import com.cc.mdb.BaseTest;
import org.junit.Test;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 聚合查询
 *      $project	        指定返回字段
 *      $lookup	            多表关联
 *      $unwind	            数组拆分
 *      $match	            筛选条件
 *      $sort	            排序
 *      $limit	            分页
 *      $skip	            跳过
 *      $group	            根据id(可自定义)分组
 *      $sum	            分组后求和
 *      $first	            分组后取第一条
 *      $last	            分组后取最后一条
 *      $addToSet	        分组后添加到list
 *      $cond	            可以做 if-else
 * @author CC
 * @since 2023/4/20 0020
 */
public class TestMongoAgg extends BaseTest {

    @Resource
    private MongoTemplate mongoTemplate;

    private static final String COLLECTION_NAME = "USER";

    /** 分组
     */
    @Test
    public void test00()throws Exception{
        Aggregation groupAgg = Aggregation.newAggregation(
                Aggregation.group("age") // 分组条件
                        .first("age").as("age_R")     // 获取分组后查询到的该字段的第一个值
//                        .first("school.sId").as("sId_R")
                        .sum("age").as("sum_age_R")  // 按分组对该字段求和
                        .avg("age").as("avg_age_R")  // 按分组求该字段平均值
                        .sum("id").as("sum_id_R")    // 按age分组后求id的和
                        .min("id").as("min_id_R")    // 按age分组后求id的最小值
                        .max("id").as("max_id_R")    // 按age分组后求id的最大值
        );

        AggregationResults<JSONObject> results = mongoTemplate.aggregate(groupAgg, COLLECTION_NAME, JSONObject.class);
        List<JSONObject> res = results.getMappedResults();
        System.out.println(res);


    }

    /** 聚合查询:数组拆分 + 指定返回字段 + 排序 + 分页
     */
    @Test
    public void testAgg01()throws Exception{
        // 1. 配置聚合查询
        // 1.1. 将school字段分解成数组
        UnwindOperation unwind = Aggregation.unwind("school");
        // 1.2. 获取school.sId的属性中大于2的对象
        MatchOperation match = Aggregation.match(Criteria.where("school.sId").gt(2));
        // 1.3. 显示的字段
        ProjectionOperation project = Aggregation.project("_id", "school.sId",
                "school.sName", "name", "id", "age", "email");

        // 1.4. 查询所有
        Aggregation aggregation = Aggregation.newAggregation(
                unwind,
                match,
                project
        );
        // 1.5. 查询数量:把数量封装在totalCount这个值中
        Aggregation countAgg = Aggregation.newAggregation(
                unwind,
                match,
                Aggregation.count().as("totalCount")
        );
        // 1.6. 排序+分页
        Aggregation sortAndSkipLimitAgg = Aggregation.newAggregation(
                unwind,
                match,
                project,
                // 1.6.1. 排序:先按照sId升序,再按照id降序
                Aggregation.sort(Sort.Direction.ASC,"sId")
                        .and(Sort.Direction.DESC,"id"),
                // 1.6.2. 分页
                Aggregation.skip(0L),
                Aggregation.limit(2L)
        );

        // 2. 查询
        // 2.1. 查询全部
        AggregationResults<JSONObject> results = mongoTemplate.aggregate(aggregation, COLLECTION_NAME, JSONObject.class);
        // 2.1.1. 获取映射结果
        List<JSONObject> allResult = results.getMappedResults();
        allResult.forEach(System.out::println);
        // 2.2. 查询数量
        AggregationResults<JSONObject> resultCount = mongoTemplate.aggregate(countAgg, COLLECTION_NAME, JSONObject.class);
        JSONObject jsonObject = resultCount.getUniqueMappedResult();
        System.out.println(jsonObject);
        Object totalCount = jsonObject.get("totalCount");
        System.out.println("总数:" + totalCount);

        // 2.3. 排序+分页查询
        AggregationResults<JSONObject> sortSkip = mongoTemplate.aggregate(sortAndSkipLimitAgg, COLLECTION_NAME, JSONObject.class);
        List<JSONObject> mappedResults = sortSkip.getMappedResults();
        System.out.println(mappedResults);

        //获取原始结果
//        Document rawResults = results.getRawResults();
        //获取唯一映射结果(只获取一个值)
//        JSONObject uniqueMappedResult = results.getUniqueMappedResult();
        //获取服务器使用情况
//        String serverUsed = results.getServerUsed();
        //循环:和mappedResults循环一样的
//        results.forEach(result -> {
//            System.out.println(result);
//        });
    }

    //添加聚合查询的数据
    @Test
    public void testAgg02() throws Exception {
        //写入复杂数据 —— 有子文档(json数据中有下级)
        List<JSONObject> vos = new ArrayList<>();
        for (int i = 1; i < 20; i++) {
            JSONObject result = new JSONObject();
            String aa = i + "" + i + "" + i + "";
            result.put("id", aa);
            result.put("name", "cscs" + aa);
            int age = 123;
            if (i >= 10){
                age = 345;
            }
            result.put("age", age);
            result.put("email", "11@qq.com");

            List<JSONObject> jss = new ArrayList<>();
            if (i < 6){
                for (int j = 1; j < 3; j++) {
                    JSONObject js = new JSONObject();
                    js.put("sId", j * i);
                    js.put("sName", "学校" + aa);
                    js.put("sNo", "学校编号" + aa);
                    js.put("sTab", j * i);
                    jss.add(js);
                }
            }
            result.put("school", jss);
            vos.add(result);
        }
        Collection<JSONObject> user3 = mongoTemplate.insert(vos, COLLECTION_NAME);
        System.out.println(user3);
    }


}

本文转载于网络 如有侵权请联系删除

相关文章

  • 中国医学影像人工智能20年回顾和展望

    来源:中国图像图形学报、极市平台本文约11000字,建议阅读15+分钟本文回顾并简要总结了近20年国内医学影像人工智能发展进程中的重要事件。复制本文回顾并简要总结了近20年国内医学影像人工智能发展进程中的重要事件,包括国内主办的医学影像人工智能知名国际和国内会议、《中国医学影像AI白皮书》的发布以及国内同行在新冠肺炎COVID-19期间的贡献。最后,我们展望了国内医学影像人工智能领域未来的发展趋势。在过去20年里,医学影像技术、人工智能技术以及这两项技术相结合的临床应用都取得了长足发展。中国在该领域的研究也取得卓越成就,并且在全世界范围内的贡献比例仍在逐步提高。为了记录和总结国内同行的科研成果,中国医学影像人工智能20年回顾和展望(发表于《中国图象图形学报》2022年第3期“医学影像及临床应用”专刊)一文对中国医学影像人工智能过去20年的发展历程进行回顾和展望。论文来源:《中国图象图形学报》2022年第3期“医学影像及临床应用”专刊 引用格式:蒋希,袁奕萱,王雅萍,肖振祥,朱美芦,陈泽华,刘天明,沈定刚.2022.中国医学影像人工智能20年回顾和展望.中国图象图形学报,27(3):65

  • 修改ubuntu上的pycharm镜像源,详细步骤

    毕竟用官方的链接下载简直像个蜗牛一样,等得不耐烦,于是我就去用了清华镜像源。不废话了,上步骤!! 第一个配置: 第一步:files-setting(就是进入设置的意思) 第二步:找到project这里,双击右边其中一个模块进入 第三步:点击ManageRepositires 第四步:点击左下角像个笔的那个图标 在这个方框输入镜像源地址,点击ok就行,我已经设置好了 在这里我多介绍几个镜像源,根据自己喜好选择吧,个人偏向清华的: 清华:https://pypi.tuna.tsinghua.edu.cn/simple豆瓣:http://pypi.douban.com/simple/阿里:http://mirrors.aliyun.com/pypi/simple/最后一步:重启pycharm,就是关掉再打开的意思第二个配置:我发现上面这样的设置也只能在这系统下载,特别麻烦,我还是想要用window上那样,使用pipinstall下载更舒服 方法如下: 打开终端,输入cd~/.pip如果没有这个文件夹,自己创一个,输入mkdir~/.pipcd~/.pip创建或者修改pip.conf

  • 浅谈弹幕的设计

    背景为了创造更好的多媒体体验,许多视频网站都添加了社交机制,使用户可以在媒体时间轴上的特定点发布评论和查看其他人的评论,其中一种机制被称为弹幕(dànmù),在日语中也称为コメント(comment)或者弾幕(danmaku),在播放过程中,可能会出现大量评论和注释,并且直接渲染在视频上。弹幕最初是由日本视频网站Niconico(ニコニコ)引入的。在中国,除了在Bilibili和AcFun等弹幕视频网站中使用之外,其他主流视频网站(例如腾讯视频,爱奇艺视频,优酷视频和咪咕视频)中的视频播放器也支持弹幕。形式单条弹幕的基本模式有三种:滚动弹幕:自右向左滚动过屏幕的弹幕,以自上而下的优先度展示。顶部弹幕:自上而下静止居中的弹幕、以自上而下的优先度展示。底部弹幕:自下而上静止居中的弹幕、以自下而上的优先度展示。为什么需要弹幕从用户体验角度出发——没有弹幕之前在没有弹幕之前,我们一般是通过评论或者聊天室的方式去进行互动:(如上,左边视频,右边互动区)传统互动方式带来的问题是,当我们的人眼的关注点在视频上时,是没办法进行“一眼二用”的,简单的来说就是,你没办法让你的两颗眼珠子往不同的方向看。这样带

  • 短视频app源码开发,如何添加启动界面

    打开短视频app源码时,一般都会有一个启动界面,启动界面除了会展示APP的logo外,大多数都会将广告直接放到上面,起到引流盈利的目的。在这里为大家提供两种不同的短视频app源码开发中启动界面设置的方式:一种是两个Activity实现,即需要一个启动界面的Activity和一个启动界面执行完后跳转到的Activity另一种则是由一个Ativity实现,但相对代码量也增加了一些。下面则开始介绍两种设置启动画面的方式:第一种(两个Activity):启动界面的ActivitypublicclassSplashActivityextendsActivity{ privatestaticintSPLASH_DISPLAY_LENGHT=2000;//延迟2秒 @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_NO_TITLE);//去掉标题 setContentVie

  • lettuce和hbase中对netty的使用你都了解吗?

    之前的两篇文章中咱们有详细地聊过关于lettuce的pipeline以及spring-data-redis对其封装的细节。本篇紧接着上面篇以connectionPoolingProvider为入口,对lettuce基于netty处理IO事件的线程池进行进一步地分析。lettuceEventLoopGroup初始化在使用lettuce作为redis连接池时,在上一节中我们知道,lettuce中维护连接有两种使用连接池的方式,目前一种已经废弃,另一种大家正在使用的版本是apachecommonspool。咱们来回顾下。从连接池获取连接的入口org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider#getConnection:@Override public<TextendsStatefulConnection<?,?>>TgetConnection(Class<T>connectionType){ GenericObjectPool<Stat

  • Mysql常用sql语句(14)- 多表查询

    测试必备的Mysql常用sql语句系列https://www.cnblogs.com/poloyy/category/1683347.html前言实际工作中,每次查询基本都是需要结合多个表去查询数据,所以Mysql的多表查询我们必须掌握多表查询可以是两张表,也可以是很多张表,取决于需要查询的数据要关联多少张表有哪些多表查询crossjoin:交叉连接innerjoin:内连接leftjoin:左外连接rightjoin:右外连接union、unionall:全连接多表查询的区别查询类型简述图表innerjoin获取两个表中字段相互匹配关系的记录 即两表记录都不为null才会返回leftjoin获取左表所有记录 右表为空的字段补nullrightjoin获取右表所有记录 左表为空的字段补nullunion获取左右表所有记录crossjoin两张表的笛卡尔积执行SQL后面详细讲每种多表查询的时候,会用到这些数据表和数据;先跑一跑创建下哦!DROPTABLEIFEXISTS`emp`; CREATETABLE`emp`( `id`int(11)NOTNULLCOMMENT'员工编号

  • 从采集方面分析如何快速的开发一个完整的iOS直播app源码

    开发一款直播app,首先需要采集主播的视频和音频,然后传入流媒体服务器,本篇主要讲解如何采集主播的视频和音频,当前可以切换前置后置摄像头和焦点光标,但是美颜功能还没做,可以看见素颜的你,后续还会有直播的其他功能文章陆续发布。基本知识介绍AVFoundation:音视频数据采集需要用AVFoundation框架.AVCaptureDevice:硬件设备,包括麦克风、摄像头,通过该对象可以设置物理设备的一些属性(例如相机聚焦、白平衡等)AVCaptureDeviceInput:硬件输入对象,可以根据AVCaptureDevice创建对应的AVCaptureDeviceInput对象,用于管理硬件输入数据。AVCaptureOutput:硬件输出对象,用于接收各类输出数据,通常使用对应的子类AVCaptureAudioDataOutput(声音数据输出对象)、AVCaptureVideoDataOutput(视频数据输出对象)AVCaptionConnection:当把一个输入和输出添加到AVCaptureSession之后,AVCaptureSession就会在输入、输出设备之间建立连接,

  • 看!我手里有个Email收集神器

    故事背景 众所周知,在工作中,大家用到最多的便是Email来传输工作内容,因此,像一些V**信息、服务器账号密码、公司人员清单等敏感数据,均会通过Email进行传输,并且更重要的是,大部分工作人员,在传输这些数据时,是为进行过加密的。记得在某云网上也有很多相关的由于邮箱泄露引发的“悲剧”。 因此,在做SRC漏洞挖掘时,我们也可以通过Email尝试获取更多信息。但是在当今信息飞速发展的时代下,工具横飞,着实让斗友们有些无从下手不知所措,今天,斗哥准备站出来,向大家推荐一款斗哥自认为还是比较ok的Email收集工具---神器之Prowl。 神器概要 Prowl是一个电子邮件收集工具,它可以搜索与用户搜索术语相关联的Yahoo个人资料,并识别职位。它还确定了指定组织的当前工作列表。 ----摘自Github/nettitude 这款工具是由Nettitude公司中的安全团队所开发。他们的开发初衷以及开发背景,有兴趣的斗友可以到https://www.youtube.com/watch?v=3kHP5D7VZ_I&feature=youtu.be&t=6m47s观看

  • Python正则表达式初识(九)

    继续分享Python正则表达式的基础知识,今天给大家分享的特殊字符是[\u4E00-\u9FA5],这个特殊字符最好能够记下来,如果记不得的话通过百度也是可以一下子查到的。 该特殊字符是固定的写法,其代表的意思是汉字。换句话说,只要字符中是汉字,就可以通过该字符进行匹配,该特殊字符也是用中括号括起来的。具体的代码演示如下。 1、原始字符串是“加油”,两个汉字,然后将匹配模式直接为[\u4E00-\u9FA5],如下图所 可以看到此时的输出结果仅仅出现了一个“加”字,因为该匹配模式默认是匹配一个字符。 2、如何想匹配多个字符,只需要在匹配模式后面加一个“+”号即可,表示匹配连续出现的汉字,如下图所示。 此时可以看到“加油”全都匹配出来了。 3、为了进一步加强对该特殊字符的理解,现在将“加油”两字中嵌入非汉字,如下图所示。 可以看到只匹配到了“加”,但是非汉字字符“a”及其以后的字符全部都匹配不到了,因为原始字符串并不是连续出现的汉字。 4、将非汉字字符放到字符串最后边,如下图所示。 此时可以看到“加油”这两个连续的汉字可以成功匹配,但是非汉字字符匹配不到。 5、如果将“加油”中

  • 「数据架构」:主数据管理(MDM)对我的行业有什么帮助?

    虽然所有行业都存在数据质量问题;每个行业都有其独特的需求。MDM提供对于这些行业改进业务流程所需的数据合理化所需的工具.通信、媒体和公用事业通信、媒体和公用事业行业的公司面临着激烈的竞争,需要提供创新的服务才能生存。客户越来越多需要为他们量身定做的下一代服务。作为行业融合提供如果是捆绑服务,以客户为中心的观点是至关重要的。当前的系统以产品为中心,使360度视角难以获得,减少了向上销售和交叉销售的机会。MDM通过减少客户信息,帮助组织合理化客户信息复制并创建一个惟一的客户标识符,该标识符用于跨竖井交叉引用数据系统生成客户所需的单个视图。日用消费品消费品包装(CPG)公司面临着不断变化和增加全球竞争。他们必须努力满足推出有利可图的产品的高要求同时提高分销和运营效率。然而,在大公司、关键的管理信息被隔离在整个企业的不同系统中。随着数据量的激增和数据复杂度的不断增加,CPG公司的业务也在不断增加今天,这个问题正在加剧。从客户和产品数据中获得洞察实时促销优化,分类/SKU盈利报告和需求预测是最大化性能的关键。数据集成给了CPG公司能够创造一个整体的运营观和销售。分享“最好的真相”组织内部和跨补货

  • 3.1 Contour绘制

    首先一起学习利用百度的开源项目绘制contour,百度搜索“echartsheatmap”,找到热力图的一个案例(http://echarts.baidu.com/examples/#chart-type-heatmap),点击这个案例:发现这个案例代码量很多(近400行),不便于初学: 经过梳理我们发现,该程序的核心在于参数option(第25行),这个参数给定了绘制云图所包含的数据,我们不妨把数据修改简单一点。程序主要有三个关键参数xData,yData和data,分别表示x轴的坐标值数组、y轴的坐标值数组、以及云图数据(等高值)。我们把数据修改一下:1.varxData=[]; 2.varyData=[]; 3. 4.functiongenerateData(theta,min,max){ 5.vardata=[]; 6.for(vari=0;i<=200;i++){ 7.for(varj=0;j<=100;j++){ 8.//varx=(max-min)*i/200+min; 9.//vary=(max-min)*j/100+min; 10.data.push([i

  • 只知道GAN你就OUT了——VAE背后的哲学思想及数学原理

    引言 短短三年时间,变分编码器VAE(VariationalAuto-encoder)同GAN一样,成为无监督复杂概率分布学习的最流行的方法。VAE之所以流行,是因为它建立在标准函数逼近单元,即神经网络,此外它可以利用随机梯度下降进行优化。本文将解释重点介绍VAE背后的哲学思想和直观认识及其数学原理。VAE的最大特点是模仿自动编码机的学习预测机制,在可测函数之间进行编码、解码。同GAN类似,其最重要的idea是基于一个令人惊叹的数学事实:对于一个目标概率分布,给定任何一种概率分布,总存在一个可微的可测函数,将其映射到另一种概率分布,使得这种概率分布与目标的概率分布任意的接近。看到这里读者可能会一头雾水。下面我们来一一阐明其中的含义。可测函数之间的编解码?什么样的可测函数?可测函数是测度论中的概念,它是真实世界的随机事件到数学世界的随机事件的映射。当然,在形式化问题过程中我们需要对这里面的所有事件进行量化,于是我们自然地会将这个数学世界选取为欧式空间,相应的σ-代数也就是Borelσ-代数了。回到选取可测函数的问题。VAE的一个重要的哲学思想是,遵从图模型,我们希望生成的样本是由某些隐含

  • cv2.cornerHarris()详解 python+OpenCV 中的 Harris 角点检测

    参考文献----------OpenCV-Python-Toturial-中文版.pdf参考博客----------http://www.bubuko.com/infodetail-2498014.html不废话进入主题:角点是一类具有特定特征的点,角点也是处在一个无论框框往哪边移动 框框内像素值都会变化很大的情况而定下来的点 可以这么去理解。。。。  如上图有三个颜色的框框,如果我们对蓝色框框进行移动,无论是水平 还是垂直的方向移动 都不会对框框内像素造成很大的变化。。。这种是内部区域  如果我们对黑色的框框进行移动,那么水平方向上移动 像素值是不会有什么太大的变化的 如果是垂直方向上移动那么就会变化很大 这种一般称为边缘区域  最后的重点  我们对红色的框框进行移动  无论是往哪个方向进行偏移 都会对框框内的像素值 造成很大的变动   那么红色框框 框住的区域的边角点  我们就称为角点     通过以上的几句话 我们大家应该大概的理解了角点是什么意思了、、、、就这样一直说下去 解释下去 肯定是比较枯燥的   大家估计都是想先看看这个cv2.cornerHarris()函数的作用是什

  • 统计学里面的百分位数是什么意思

    百分位数是一个统计学里面的概念,原来在review的elasticsearch中文文档聚合的章节里面遇到过,一直没搞明白什么意思,后来在jmeter里面又看到了这个术语,所以觉得有必要补充了解一下这个知识,下面的这个文章是网上不错的一篇文章比较通俗的通过例子解释了百分位数的含义,原文如下: jmeter里面90%Line参数正确的含义:虽然,我的上面理解有一定的道理,显然它是错误的。那看看JMeter官网是怎么说的?90%Line-90%ofthesamplestooknomorethanthistime.Theremainingsamplesatleastaslongasthis.“90%的样品没有超过这个时间,剩余的样品至少只要这个。”(拿google翻译的)没太理解是什么意思,于是,点击详细解释。90%Line(90thPercentile)isthevaluebelowwhich90%ofthesamplesfall.Theremainingsamplestooatleastaslongasthevalue.Thisisastandardstatisticalmeasure.S

  • AI 一键抠图助你快速打造活动宣传海报

    本文介绍使用PaddleHub工具快速完成人像抠图。背景我们经常看到各种大牛演讲或者活动的各种海报和宣传页,职业照造型姿势那叫一个专业。那么,学好姿势排好照片后,如何给自己做一个宣传海报呢?PS的使用当然是基础,抠图的处理也是基本功,但是复杂背景的人像,特别是发丝等细节的处理方面就非常考验技术了,甚至有时还需要像素级的抠图。现在我们可以用到的一键抠图的工具有很多,比如iPhone自带的人像抠图,当然也有很多在线的网站。今天介绍一种使用AI人像分割模型的抠图方法。安装依赖首先我们需要安装Paddle库,飞桨是百度开源的一个易用、高效、灵活、可扩展的深度学习框架。pipinstall--upgradepaddlepaddle-ihttps://mirror.baidu.com/pypi/simple复制如果要用到GPU需要前往飞桨官网[1]根据对应的CUDA版本进行不同的GPU库安装,需要安装CUDA驱动和Cudnn。PaddleHub可以便捷地获取PaddlePaddle生态下的预训练模型:pipinstall--upgradepaddlehub-ihttps://mirror.baid

  • vue基础难点总结

    vue各种各样的命令和语法的格式容易记混 vue指令-v-model修饰符 语法: v-model.修饰符="vue数据变量" .number以parseFloat转成数字类型 .trim去除首尾空白字符 .lazy在失去焦点时触发更改而非inupt时 计算属性 计算属性有缓存,提高渲染性能。 如果在页面上需要用到对现有的数据进行加工得到新数据,则时要使用计算属性 普通写法 computed:{ //属性名字(计算属性名称) //属性的值(计算属性处理函数) 计算属性名1(){ //对依赖的数据进行处理,且进行return return }, 复制 完整写法 computed:{ "属性名":{ set(值){ }, get(){ return"值" } } } 复制 vue监听器 可以监听数据(data/computed等)的值的改变。数据的值有类型:基本数据类型,引用数据类型 深度监听 watch:{ "要监听的属性名":{ immediate:true,//立即执行 deep:true,//深度监听复杂类型内变化 handler(newVal,oldVal){ }

  • 这些所谓的自媒体,没话可聊,开始尬聊了

      先来看看这个   https://new.qq.com/omn/20220530/20220530A0ALEI00.html   没话可聊,开始尬聊了? 还得辩证地看一下问题么, 有没有短板还需要你在这边科普一下么, 别人吹不吹,你又管不着, 磨磨唧唧一大堆,凑字么,写个小说都比你现在工资高。     我可没转,看明白,我是截图,加打了码的    

  • Node.js模块化你所需要知道的事

    正文 在Node.js中,内置了两个模块来进行模块化管理,这两个模块也是两个我们非常熟悉的关键字:require和module。内置意味着我们可以在全局范围内使用这两个模块,而无需像其他模块一样,需要先引用再使用。 无需require('require')orrequire('module')复制 在Node.js中引用一个模块并不是什么难事儿,很简单: constconfig=require('/path/to/file')复制 但实际上,这句简单的代码执行了一共五个步骤:  了解这五个步骤有助于我们了解Node.js模块化的基本原理,也能让我们甄别一些陷阱,让我们简单概括下这五个步骤都做了什么: Resolving: 找到待引用的目标模块,并生成绝对路径。 Loading: 判断待引用的模块内容是什么类型,它可能是.json文件、.js文件或者.node文件。 Wrapping: 顾名思义,包装被引用的模块。通过包装,让模块具有私有作用域。 Evaluating: 被加载的模块被真正的解析和处理执行。 Caching: 

  • [NOI2018]冒泡排序(卡特兰数)

    首先有一个性质,达到下界的充要条件是排不能存在长度大于\(2\)的下降子序列。 证明: 要想达到下界\(\frac{1}{2}\sum|i-p_i|\),等于每次交换相邻两个数时,这两个数一定是往目的方向移动。 如果存在长度大于\(2\)的下降子序列,那么第一次,对于这个子序列中的中间的一个数\(x\),之前比\(x\)大的数一定会和它产生交换,它就会往前移动,而它又会和后面比它小的数交换,所以它也至少会往后移动一次。所以它一定会在中途产生“掉头”的代价。 有了这个性质后,我们问题变成求不存在长度大于\(2\)的下降子序列的排列数。 设\(f_{i,j}\)表示长度为\(i\)的排列,第一个数是\(j\)的方案数。 分几种情况转移: 如果第二个数\(k\)大于\(j\),那么方案数就是\(f_{i-1,k}\)。 如果第二个数\(k\)小于\(j\),且不等于\(1\),那么一定会存在为\((j,k,1)\)这样的下降子序列,所以方案数为\(0\)。 如果第二个数为\(1\),那么小于\(j\)的数一定是依次排列的(位置可以不连续),且之后的方案我们可以对应一种合法的方案(\(1\)换

  • 蜕变测试概述及典型案例

    1、蜕变测试概述 程序的执行结果不能预知的现象在测试理论中称为“Oracle问题”,即预期结果不知道。 例如测试sin(x)函数时,sin270的预期结果并不知道,这时就无法验证当x=270时程序执行的正确性。 Oracle问题是“软件测试中最困难的任务”,它导致测试人员只能选择一些可以预知结果的特殊测试用例进行测试,而不能完整有效地进行测试。 蜕变测试是一种特殊的黑盒测试方法,蜕变测试依据被测软件的领域知识和软件的实现方法建立蜕变关系(MetamorphicRelation,MR),利用蜕变关系来生成新的测试用例,通过验证蜕变关系是否被保持来决定测试是否通过。蜕变关系(MetamorphicRelation,MR)是指多次执行目标程序时,输入与输出之间期望遵循的关系。 蜕变测试依据蜕变关系生成更多的后续测试用例,测试时就会多次执行目标程序时,使得程序可以进一步被验证。 2、蜕变测试的典型案例 例1:测试sin函数。 这些蜕变关系MR如下所示:R1:sin(x)=sin(x+2π)R2:sin(x)=-sin(x+π)R3:-sin(-x)=sin(x)R4:sin(x)=sin(π-

  • vue项目路由、组件优化及使用nodeJs自动创建文件

    vue项目路由、组件优化及使用nodeJs自动创建文件 我们在使用Vue进行开发的过程中,每次都需要先创建路由,再在主文件中引入模块路由。如下: //目录结构 -router ---index.js ---modules //现在我们创建一条新路由 ---modules -----layout.js //layout.js module.export[ { name:'...' path:'...', component:()=>import('@/views/modules/layout') } ] //然后在index.js文件中引入layout模块的内容 importLayoutfrom'./modules/layout.js' constmainRouter={ path:'/', componemt:()=>import('@/views') children:[ ...Layout ] } 复制 这样每次创建后进行引入的方式,一方面重复性工作显得单调,另一方面,index.js中引入过多模块会导致代码看起来重复性太多,不够优雅。为此,我们可以尝试这样

相关推荐

推荐阅读