MongoDB 的日常使用

news2024/11/25 23:48:51

一、简介 

1、 常见的数据库分类

RDBMS(关系型数据库):常见的关系型数据库有 Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL;
NoSQL(非关系型数据库):常见的非关系型数据库有 MongoDB、Redis、Voldemort、Cassandra、Riak、Couchbase、CouchDB 等。

1.NoSQL 优点

易扩展:NoSQL 数据库种类繁多,但它们都有一个共同的特点,那就是都去掉了关系型数据库的关系型特性,数据与数据之间没有关系,这样就非常容易扩展,无形之间也在架构的层面上带来了可扩展的能力;
大数据量,高性能:NoSQL 数据库都具有非常高的读写性能,尤其是在处理庞大数据时表现优秀;
灵活:NoSQL 随时都可以存储任意类型的数据,无须提前为要存储的数据建立字段;
高可用:NoSQL 在不太影响性能的情况下,就可以方便地实现高可用的架构,比如 Cassandra、HBase 模型,通过复制模型也能实现高可用。

2.NoSQL 适用场景

数据模型比较简单;
对灵活性要求很强的系统;
对数据库性能要求较高;
不需要高度的数据一致性;
对于给定 key,比较容易映射复杂值的环境。

2、 MongoDB

概述:MongoDB是由C++语言编写的,是一个基于分布式文件存储的非关系型数据库。MongoDB又被称为最像关系型数据库的非关系性数据库。
优势:MongoDB的优势在于可以存放海量数据,具备强大的查询功能,是一个独立的、面向集合文档形式的数据库。

1.MongoDB特点

存储性
面向集合:数据被分组存储在数据集中也被称为集合。每个集合在数据库中都有一个唯一的标识名,并且可以包含多个的文档。
面向文档:存储在集合中的文档,被存储为key-values键对值的形式。键用于唯一标识一个文档,为字符串类型,而值可以是各种的文件类型。
高效二进制数据存储:包括大型对象,例如视频,MongoDB使用二进制格式存储数据,可以保存任何类型的数据对象
操作性
完全索引: 可在任意属性上建立索引,包含内部对象。
强大的聚合工具:如count、group等,支持使用MapReduce完成复杂的聚合任务。
支持Perl、PHP、Java、Python等现在主流开发语言的驱动程序
可用性
支持复制和数据恢复:支持主从复制机制,可以实现数据备份、故障恢复、读扩展等功能,MongoDB数据库的主从复制主挂了从会代替主。
自动处理分片:支持集群自动切分数据,对数据进行分片可以使集群存储更多的数据,实现更大的负载,也可以保证存储的负载均衡。

二、MongoDB的属性和常用语法 

1、属性

1、 数据类型

String  字符串类型,是最常用的数据类型,不过在 MongoDB 中,只有 UTF-8 编码的字符串才是合法的
Integer    整型,用于存储数值。根据您使用服务器的不同,整型可以分为 32 位或 64 位两种
Boolean    布尔型,用于存储布尔类型的值(true/false)
Double 双精度浮点型,用于存储浮点型(小数)数据
Min/Max keys   将一个值与 BSON 元素的最低值和最高值相对比
Array  数组类型,用于将数组、列表或多个值存储在一个键中
Timestamp  时间戳,记录文档修改或添加的具体时间
Object 用于内嵌文档
Null   用于创建空值
Symbol 符号,该数据类型于字符串类型类似,不同的是,它一般用于采用特殊符号类型的语言
Date   日期时间,用 UNIX 时间格式来存储当前日期或时间,您可以创建 Date 对象并将 date、month、year 的值传递给 Date 对象来指定自己的日期时间
Object ID  对象 ID,用于创建文档的 ID
Binary Data    二进制数据,用于存储二进制数据
Code   代码类型,用于在文档中存储 JavaScript 代码
Regular expression 正则表达式类型,用于存储正则表达式

Object ID 类似于关系型数据库中的主键 ID,在 MongoDB 中 Object ID 由 12 字节的字符组成,
601e2b6b aa203c c89f 2d31aa
  ↑      ↑     ↑     ↑
时间戳  机器码 进程id 计数器

Timestamps(时间戳)
与 Date 类型不同,Timestamps 由一个 64 位的值构成,其中:
前 32 位是一个 Unix 时间戳(由 Unix 纪元(1970.1.1)开始到现在经过的秒数);
后 32 位是一秒内的操作序数。

Date
是一个 64 位的对象,其中存放了从 Unix 纪元(1970.1.1)开始到现在经历的毫秒数,Date 类型是有符号的,负值则表示 1970.1.1 之前的时间。

2、 内置角色

1.数据库用户角色:read、readWrite;
2.数据库管理角色:dbAdmin、dbOwner、userAdmin;
3.集群管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;
4.备份恢复角色:backup、restore;
5.所有数据库角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase
6.超级用户角色:root
提供了系统超级用户的访问(dbOwner 、userAdmin、userAdminAnyDatabase)

3、MongoDB默认四个数据库

config: 集群中使用的,分片数据库
admin: 保存用户信息、权限的数据库
local: local的数据只存在于本地数据,不会被同步到其他数据库
test: test为MongoDB默认登录的数据库,只要不知道数据库登录,那么登录的就是test

2、常用语法

1.DDL

创建数据库
use DATABASE_NAME //如果数据库不存在,则创建数据库,否则切换到指定数据库。创建数据库,必须要有数据,否则显示数据库的时候,不会显示。
显示数据库
show dbs //查看所有数据库 ,注意 数据库一定要有数据 不然 无法显示,默认使用test
db //显示当前数据库。
删除数据库
db.dropDatabase() //删除当前数据库,默认为 test,你可以使用 db 命令查看当前数据库名。

查看当前数据所有表(集合)
show tables //只显示有数据的表
show collections //两种方法都可以
创建表(集合)
db.createCollection(name, options)
案例db.createCollection("table2"),注意db是当前数据库,不能写数据库名字。
//options: 可选参数, 指定有关内存大小及索引的选项
删除当前数据库的表(集合)
db.manong.drop()

对某一行数据添加字段
db.manong.update({"age":18},{$set:{'title':'哈哈哈'}})
如果是所有的数据都增加这个字段值为'title':'哈哈哈'
db.manong.update({},{$set:{'title':哈哈哈'}})
对所有数据删除字段
db.manong.update({},{$unset:{'content':''}},false, true)
对指定数据删除字段
db.manong.update({"name": "shell"}, {$unset:{"script_type":"kshell"}})
对某一行数据字段修改字段值
db.manong.update_many({'address': '北京'}, {'$set': {'salary': 9999}})
修改字段名
db.getCollection('集合名').updateMany( {}, { $rename: { "老字段名": "新字段名" } } )
多字段修改
db.manong.updateMany({},{$rename:{"name":"studentName", "age":"studentAge"}});
查看字段
db.manong.find({"age":18}).pretty();

2.DML

db.users.find(): select * from users
db.users.find({ "age" : 27}): select * from users where age = 27
db.users.find({ "username" : "joe", "age" : 27}): select * from users where "username" = "joe" and age = 27
db.users.find({}, { "username" : 1, "email" : 1}): select username, email from users
db.users.find({}, { "username" : 1, "_id" : 0}): //no case // 即时加上了列筛选,_id 也会返回;必须显式的阻止_id 返回
db.users.find({ "age" : {"$gte" : 18, "$lte" : 30}}): select * from users where age >=18 and age <= 30 // $lt(<) $lte(<=) $gt(>) $gte(>=)
db.users.find({ "username" : {"$ne" : "joe"}}): select * from users where username <> "joe"
db.users.find({ "ticket_no" : {"$in" : [725, 542, 390]}}): select * from users where ticket_no in (725, 542, 390)
db.users.find({"ticket_no" : {"$nin" : [725, 542, 390]}}): select * from users where ticket_no not in (725, 542, 390)
db.users.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]}): select * form users where ticket_no = 725 or winner = true
db.users.find({ "id_num" : {"$mod" : [5, 1]}}): select * from users where (id_num mod 5) = 1
db.users.find({ "$not": {"age" : 27}}): select * from users where not (age = 27)
db.users.find({"username" : {"$in" : [null], "$exists" : true}}): select * from users where username is null // 如果直接通过 find ({"username" : null}) 进行查询,那么连带 "没有 username" 的纪录一并筛选出来
db.users.find({"name" : /joey?/i}):// 正则查询,value 是符合 PCRE 的表达式
db.food.find({fruit : {$all : ["apple", "banana"]}}): // 对数组的查询,字段 fruit 中,既包含 "apple", 又包含 "banana" 的纪录
db.food.find({"fruit.2" : "peach"}): // 对数组的查询,字段 fruit 中,第 3 个 (从 0 开始) 元素是 peach 的纪录
db.food.find({"fruit" : {"$size" : 3}}): // 对数组的查询,查询数组元素个数是 3 的记录,$size 前面无法和其他的操作符复合使用
db.users.findOne(criteria, {"comments" : {"$slice" : 10}}):  // 对数组的查询,只返回数组 comments 中的前十条,还可以 {"$slice" : -10}, {"$slice" : [23, 10]}; 分别返回最后 10 条,和中间 10 条
db.people.find({"name.first" : "Joe", "name.last" : "Schmoe"}): // 嵌套查询
db.blog.find({"comments" : {"$elemMatch" : {"author" : "joe", "score" : {"$gte" : 5}}}}): // 嵌套查询,仅当嵌套的元素是数组时使用,
db.foo.find({"$where" : "this.x + this.y == 10"}): // 复杂的查询,$where 当然是非常方便的,但效率低下。对于复杂查询,考虑的顺序应当是 正则 -> MapReduce -> $where
db.foo.find({"$where" : "function() { return this.x + this.y == 10; }"}): // $where 可以支持 javascript 函数作为查询条件
db.foo.find().sort({"x" : 1}).limit(1).skip(10): // 返回第 (10, 11] 条,按 "x" 进行排序;三个 limit 的顺序是任意的,应该尽量避免 skip 中使用 large-number

 

三、Spring整合MongoDB 

1、 配置

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
spring:
  data:
    mongodb:
      host: 127.0.0.1
      database: test
      port: 27017
      # 也可用uri   mongodb://127.0.0.1:27017/test

2、JPA 方式

1.创建实体类

public class MyUser {
	@Id
    private String id;

    private String name;

    private Integer age;

    public MyUser() {}

    public MyUser(String id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "MyUser{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

 2.接口和测试类

/**
 * 继承 MongoRepository 即可,不要实现
 */
public interface MyUserRepository extends MongoRepository<MyUser, String> {
}


@SpringBootTest
public class MyUserRepositoryTest {

    @Autowired
    private MyUserRepository myUserRepository;

    /**
     * 插入单条数据
     */
    @Test
    public void insertOne() {
        MyUser user = new MyUser("11", "tom", 18);
        myUserRepository.insert(user);
    }

    /**
     * 插入多条数据
     */
    @Test
    public void insertMany() {
		MyUser user01 = new MyUser("11", "tom", 18);
		MyUser user02 = new MyUser("22", "jake", 22);
        List<MyUser> list = new ArrayList<>();
        list.add(user01);
        list.add(user02);
        myUserRepository.insert(list);
    }
	
	/**
     * 删除操作
     */
    @Test
    public void remove() {
        //根据id删除单个对象
        myUserRepository.deleteById("11");

        //根据字段删除 
        Student student = new Student();
        student.setAge(22);
        myUserRepository.delete(student);

        //根据字段删除多个
        MyUser user02 = new Student();
        user02.setName("jerry");
        List<MyUser> list = new ArrayList<>();
        list.add(user02);
        myUserRepository.deleteAll(list);
		
        //删除所有
        myUserRepository.deleteAll();
    }
	
    /**
     * 修改数据
     */
    @Test
    public void update() {
        Optional<MyUser> op = myUserRepository.findById("11");
        MyUser user = op.get();
        user.setAge(22);
        myUserRepository.save(user);
    }

    /**
     * 查询数据
     */
    @Test
    public void query() {
        //根据Id查询单个对象
        Optional<MyUser> stuOp = myUserRepository.findById("01");
        System.out.println(stuOp.get());

        //根据字段查询单个对象
        MyUser user = new MyUser();
        user.setAge(19);
        Optional<MyUser> stuOp1 = myUserRepository.findOne(Example.of(user));
        System.out.println(stuOp1.get());

        //根据id列表查询多个对象
        Iterable<MyUser> itStu = myUserRepository.findAllById(Arrays.asList(new String[]{"001", "002"}));
        Iterator<MyUser> itor = itStu.iterator();
        while (itor.hasNext())
            System.out.println(itor.next());

        //查询所有
        List<MyUser> all = myUserRepository.findAll();

        //查询所有并排序
        List<MyUser> all1 = myUserRepository.findAll(Sort.by(Sort.Order.desc("studentId"), Sort.Order.asc("studentName")));
        for (MyUser use : all1)
            System.out.println(use);

        //根据条件查询所有并排序
        MyUser user01 = new MyUser();
        user01.setName("tom");
        List<MyUser> all2 = myUserRepository.findAll(Example.of(user01), Sort.by(Sort.Order.desc("studentId"), Sort.Order.asc("studentName")));
        for (MyUser use : all2)
            System.out.println(use);

        //根据条件查询所有并排序,且分页
        Pageable pageable = PageRequest.of(0, 2);
        Page<MyUser> all3 = myUserRepository.findAll(pageable);
        List<MyUser> content = all3.getContent();
        for (MyUser use : content)
            System.out.println(use);
    }

    /**
     * 其他操作
     */
    @Test
    public void other() {
        //count
        long count = myUserRepository.count();
        System.out.println(count);
        MyUser user = new MyUser();
        user.setAge(18);
        long count1 = myUserRepository.count(Example.of(user));
        System.out.println(count1);

        //exists
        boolean exists = myUserRepository.exists(Example.of(user));
        System.out.println(exists);
        boolean b = myUserRepository.existsById("001");
        System.out.println(b);
    }

}

3、MongoTemplate 方式

1.接口

public interface UserDao {

    //插入单个对象
    void addOne(MyUser user);

    //根据id删除单个对象
    void deleteOneById(String  studentId);

    //修改单个对象
    void updateOne(MyUser user);

    //根据id获取单个对象
    MyUser findOneById(String studentId);
    
    //获取全部学生
    List<MyUser> findAll();
}

2.实现类

public class UserDaoImpl implements UserDao {

    @Autowired
    private MongoTemplate mongoTemplate;


    @Override
    public void addOne(MyUser user) {
        mongoTemplate.save(user);
    }

    @Override
    public void deleteOneById(String studentId) {
        MyUser stu = mongoTemplate.findById(studentId, MyUser.class);
        if (stu != null)
            mongoTemplate.remove(stu);

    }

    @Override
    public void updateOne(MyUser user) {
        mongoTemplate.save(user);

    }

    @Override
    public MyUser findOneById(String id) {
        return mongoTemplate.findById(id, MyUser.class);
    }

    @Override
    public List<MyUser> findAll() {
        return mongoTemplate.findAll(MyUser.class);
    }
}

3.MongoTemplate的其它用法

Criteria
eq:等于,第一个参数是对象属性,第二个参数是值
allEq:参数为一个Map对象,相当于多个eq的叠加
gt:大于
ge:大于等于
lt:小于
le:小于等于
between:在两个值之间Expression.between('age',new Integer(10),new Integer(20));
like:like查询
in:in查询

is查询:
Query query = new Query();
// where...is... 相当于 where ? = ?
query.addCriteria(Criteria.where("数据库字段名").is("你的参数"));
// findOne 返回的是一个对象 Class代表你的表对应的映射类
mongoTemplate.findOne(query, Class.class);
// find 返回的是数组
mongoTemplate.find(query, Class.class);

in查询:
ArrayList<String> list = new ArrayList<>();
// list代表你的数据
Query query = Query.query(Criteria.where("数据库字段").in(list));
mongoTemplate.find(query, Class.class);
// 如果想要查询指定的数据是否在数据库的数组中,可以用以下方法。
Query query = Query.query(Criteria.where("数据库字段(数组)").is("你的数组"));

字符模糊查询:
Query query = Query.query(Criteria.where("name").regex("小"));

指定字段不返回:
query.fields().exclude("field");

数组中添加或删除一条数据:
Query query = Query.query(Criteria.where("_id").is("id"));
Update update = new Update(); 
// push方法可以在数组中添加一条数据。
// pull方法可以在数组中删除一条数据。
// update.pull()。
update.push("字段名称", "data");
mongoTemplate.updateFirst(query, update, Class.class);

// 分页
query.limit(10);
// 排序
Sort sort=Sort.by(Sort.Direction.DESC,"timestamp");
query.with(sort);

四、MongoDB的内部

1、索引

Cassandra、Elasticsearch (Lucene)、Google Bigtable、Apache HBase、LevelDB 和 RocksDB 这些当前比较流行的 NoSQL 数据库存储引擎是基于 LSM 开发的。
MongoDB 虽然是 NoSQL 的,但是其存储引擎 Wired Tiger 却是用的 B+Tree。
MongoDB 的索引和 MySql 的索引有点不一样,它的索引在创建时必须指定顺序(1:升序,-1:降序),同时所有的集合都有一个默认索引 _id,这是一个唯一索引,类似 MySql 的主键。

1.索引类型有

单字段索引:建立在单个字段上的索引,索引创建的排序顺序无所谓,MongoDB 可以头/尾开始遍历。
复合索引:建立在多个字段上的索引。
   多 key 索引:我们知道 MongoDB 的一个字段可能是数组,在对这种字段创建索引时,就是多 key 索引。MongoDB 会为数组的每个值创建索引。就是说你可以按照数组里面的值做条件来查询,这个时候依然会走索引。
Hash 索引:按数据的哈希值索引,用在 hash 分片集群上。
地理位置索引:基于经纬度的索引,适合 2D 和 3D 的位置查询。
文本索引: MongoDB 虽然支持全文索引,但是性能低下,暂时不建议使用。

2、集群

1.MongDB 复制集群

MongoDB 高可用的基础是复制集群,复制集群本质来说就是一份数据存多份,保证一台机器挂掉了数据不会丢失。一个副本集至少有 3 个节点组成:
一个主节点(Primary):负责整个集群的写操作入口,主节点挂掉之后会自动选出新的主节点。
一或多个从节点(Secondary):一般是 2 个或以上,从主节点同步数据,在主节点挂掉之后选举新节点。
零个或 1 个仲裁节点(Arbiter):这个是为了节约资源或者多机房容灾用,只负责主节点选举时投票不存数据,保证能有节点获得多数赞成票。
    从上面的节点类型可以看出,一个三节点的复制集群可能是 PSS 或者 PSA 结构。PSA 结构优点是节约成本,但是缺点是 Primary 挂掉之后,一些依赖 majority(多数)特性的写功能出问题,因此一般不建议使用。

2.如何保证数据一致

Journal:Journal日志是 MongoDB 的预写日志 WAL,类似 MySQL 的 redo log,然后100ms一次将Journal 日子刷盘。
Oplog:Oplog 用来做主从复制,类似 MySql 里的 binlog。MongoDB 的写操作都由 Primary 节点负责,Primary 节点会在写数据时会将操作记录在 Oplog 中,Secondary 节点通过拉取 oplog 信息,回放操作实现数据同步的。
Checkpoint:将内存变更刷新到磁盘持久化的过程。MongoDB 会每60s一次将内存中的变更刷盘,并记录当前持久化点(checkpoint),以便数据库在重启后能快速恢复数据。

3.节点选举

MongoDB 的节点选举规则能够保证在Primary挂掉之后选取的新节点一定是集群中数据最全的一个。

4.结论

1.MongoDB 宕机重启之后可以通过 checkpoint 快速恢复上一个 60s 之前的数据。
2.MongoDB 最后一个 checkpoint 到宕机期间的数据可以通过 Journal日志回放恢复。
3.Journal日志因为是 100ms 刷盘一次,因此至多会丢失 100ms 的数据(这个可以通过 WriteConcern 的参数控制不丢失,只是性能会受影响,适合可靠性要求非常严格的场景)
4.如果在写数据开启了多数写,那么就算 Primary 宕机了也是至多丢失 100ms 数据(可避免,同上)

3、分片架构

Config:配置,本质上是一个 MongoDB 的副本集,负责存储集群的各种元数据和配置,如分片地址、chunks 等
Mongos:路由服务,不存具体数据,从 Config 获取集群配置讲请求转发到特定的分片,并且整合分片结果返回给客户端。
Mongod:一般将具体的单个分片叫 mongod,实质上每个分片都是一个单独的复制集群,具备负责集群的高可用特性。

1.数据均衡的实现方式

1.分片集群上数据管理单元叫 chunk,一个 chunk 默认 64M,可选范围 1 ~ 1024M。
2.集群有多少个 chunk,每个 chunk 的范围,每个 chunk 是存在哪个分片上的,这些数据都是存储在 Config 的。
3.chunk 会在其内部包含的数据超过阈值时分裂成两个。
4.MongoDB 在运行时会自定检测不同分片上的 chunk 数,当发现最多和最少的差异超过阈值就会启动 chunk 迁移,使得每个分片上的 chunk 数差不多。
5.chunk 迁移过程叫 rebalance,会比较耗资源,因此一般要把它的执行时间设置到业务低峰期。

2.分片算法

区间分片:可以按 shardkey 做区间查询的分片算法,直接按照 shardkey 的值来分片。

hash分片:用的最多的分片算法,按 shardkey 的 hash 值来分片。hash 分片可以看作一种特殊的区间分片。

分片的本质是将 shardkey 按一定的函数变换 f(x) 之后的空间划分为一个个连续的段,每一段就是一个 chunk。
区间分片 f(x) = x;hash 分片 f(x) = hash(x)
每个 chunk 在空间中起始值是存在 Config 里面的。
当请求到 Mongos 的时候,根据 shardkey 的值算出 f(x) 的具体值为 f(shardkey),找到包含该值的 chunk,然后就能定位到数据的实际位置了。

4、其它特性

1.数据压缩

MongoDB 会自动把客户数据压缩之后再落盘。
Snappy:默认的压缩算法,压缩比 3 ~ 5 倍
Zlib:高度压缩算法,压缩比 5 ~ 7 倍
前缀压缩:索引用的压缩算法,简单理解就是丢掉重复的前缀
zstd:MongoDB 4.2 之后新增的压缩算法,拥有更好的压缩率

2.执行计划 explain 

和 MySql 的 explain 功能相同
queryPlanner:MongoDB 运行查询优化器对当前的查询进行评估并选择一个最佳的查询计划。
exectionStats:mongoDB 运行查询优化器对当前的查询进行评估并选择一个最佳的查询计划进行执行。在执行完毕后返回这个最佳执行计划执行完成时的相关统计信息。
allPlansExecution:即按照最佳的执行计划执行以及列出统计信息,如果有多个查询计划,还会列出这些非最佳执行计划部分的统计信息。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/782443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法笔记(java)——回溯篇

回溯算法解决问题最有规律性&#xff0c;借用一下卡哥的图&#xff1a; 只要遇到上述问题就可以考虑使用回溯&#xff0c;回溯法的效率并不高&#xff0c;是一种暴力解法&#xff0c;其代码是嵌套在for循环中的递归&#xff0c;用来解决暴力算法解决不了的问题&#xff0c;即…

【机器学习】模型常用评估指标

L0 范数、L1 范数、L2 范数、余弦距离 向量的范数可以简单形象理解为向量的长度&#xff0c;或者向量到零点的距离&#xff0c;亦或是相应两个点之间的距离。因此范数通常会对应一个距离概念。 L0 范数 L0 范数表示向量中非零元素的个数&#xff1a; ∣ ∣ x ∣ ∣ 0 # ( i…

elasticsearch IK分词器

说明&#xff1a;es默认的分词器对中文的识别不是特别好&#xff0c;一段话的分词是一个一个汉字&#xff0c;这显然没有达到想要的结果。 可以安装IK分词器&#xff0c;兼容中文的分词&#xff1b; IK分词器 安装 安装IK分词器&#xff0c;例如elasticsearch的容器名为es&a…

探索Java并发编程利器:LockSupport,一种高效的线程阻塞与唤醒机制

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、用法四、原理五、线程等待和唤醒的方法5.1 Lo…

Microsoft Edge 浏览器的Bing Chat

微软公司持续发力&#xff0c;推出的产品 Bing Chat 与 ChatGPT 之间的竞争愈发激烈。如今&#xff0c;微软不仅不断更新 Edge 浏览器&#xff0c;还将 Bing Chat 内置在边栏中&#xff0c;方便用户快速访问。这一举措不禁让人想起&#xff0c;Edge 浏览器如今已经是一款名副其…

Maven项目的两种打包方式-spring-boot-mavne-plugin/maven-jar-plugin

Maven项目的两种打包方式-spring-boot-mavne-plugin/maven-jar-plugin 1. 前言Maven的两种打包方式 2. 流程图3. spring-boor-maven-plugin打包4. maven-jar-plugin/maven-dependency-plugin打包 1. 前言 Maven的两种打包方式 spring-boot-maven-plugin springboot默认打包方…

新星计划联系人列表管理后台(一)-- 搭建项目开发环境

前言&#xff1a;对于前端的内容目前已经发现了很多大佬写的高质量文章&#xff0c;我这里就没必要再重复去造轮子了。接下来我会记录一下我从零到整完成此项目的过程&#xff0c;类似于日记&#xff0c;我会把我开发的步骤、过程中遇到的问题、如何解决此问题的思路、以及get到…

FPGA+EMMC 8通道存储小板

FPGA 采用XILINX公司A7100作为主芯片 AD采用AD7606及一款陀螺仪传感器&#xff0c;可以实时存储到EMMC&#xff0c;系统分为采集模式及回放模式 通过232接口对工作模式进行配置&#xff0c;采样率可以动态配置 回放采用W5100S通过TCP协议进行回放数据

福格行为模型

福格行为模型 福格行为模型也被称为“上瘾模型”&#xff0c;在工作和生活中应用非常的广泛。在工作中&#xff1a;产品设计、用户运营策略、活动设计、广告设计、游戏设计等等&#xff1b;在生活中&#xff1a;学习习惯培养、持续的健身、减肥计划等等。这些事通常大家以为是…

【N32L40X】学习笔记10-外部触发方式计数

定时器采用外部触发方式计数 也就是外部时钟源模式2 此模式由 TIMx_SMCTRL .EXCEN 选择等于 1。计数器可以在外部触发输入 ETR 的每个上升沿或下降沿 计数。 极性选择分频选择过滤选择选择外部时钟ETR模式 bsp_time_counter_ETR.h #ifndef _BSP_TIME_COUNTER_ETR_H_ #defi…

STM32(HAL库)驱动AD8232心率传感器

目录 1、简介 2、CubeMX初始化配置 2.1 基础配置 2.1.1 SYS配置 2.1.2 RCC配置 2.2 ADC外设配置 2.3 串口外设配置 2.4 GPIO配置 2.5 项目生成 3、KEIL端程序整合 3.1 串口重映射 3.2 ADC数据采集 3.3 主函数代码整合 4 硬件连接 5 效果展示 1、简介 本文通过STM32…

【车载性能优化】将线程进程运行在期望的CPU核心上

车载Android应用开发中&#xff0c;可能会出现一种奇葩的要求&#xff1a;与用户交互时应用需要全速运行&#xff0c;保证交互的流畅性&#xff0c;但是如果应用进入后台就需要怠速运行&#xff0c;让出更多的资源保证系统或前台应用的流畅度。那么基于这种需求&#xff0c;我们…

深度学习(31)——DeformableDETR(2)

深度学习&#xff08;31&#xff09;——DeformableDETR&#xff08;2&#xff09; 文章目录 深度学习&#xff08;31&#xff09;——DeformableDETR&#xff08;2&#xff09;1. backbone——Resnet502. neck——Channel mapper3. DeformableDETRHead4. DeformableDetrTransf…

Linux:多进程和多线程回环socket服务器和客户端

多进程socket服务器代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <ctype.h> #include <sys/wait.h> #i…

JWT 使用

前端访问后台a系统和b系统访问 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准&#xff08;(RFC 7519).该token被设计为紧凑且安全的&#xff0c;特别适用于分布式站点的单点登录&#xff08;SSO&#xff09;场景。 JWT的本质就是一个…

记录安装DragGAN遇到的问题

首先第一个是安装的问题 安装的envirenment.yml有很多包过时了下载不了&#xff0c;可以参考以下文章写一个requirement.txt来下载依赖环境 --extra-index-url https://download.pytorch.org/whl/cu118 numpy1.23.5 click scipy pillow9.5.0 requests tqdm4.65.0 ninja matpl…

哪些语句会被waf屏蔽?

什么是waf&#xff1a;Web应用防火墙&#xff0c;Web Application Firewall的简称。 waf的功能&#xff1a;WAF可以发现和拦截各类Web层面的攻击&#xff0c;记录攻击日志&#xff0c;实时预警提醒&#xff0c;在Web应 用本身存在缺陷的情况下保障其安全。 封IP &#xff1a;…

Qt应用开发——QLineEdit

目录 一、概述 二、属性和方法 三、信号 一、概述 QLineEdit允许用户输入和编辑单行纯文本&#xff0c;并可以使用快捷编辑功能&#xff0c;包括复制、粘贴、剪切和拖放。是项目开发中最常用的输入控件。 默认键绑定描述如下。 Left Arrow //将光标向左移…

Fourier变换极其应用(Brad G. Osgood)——第1章——Fourier级数

目录 第1章 Fourier级数 1.1 选择&#xff1a;“欢迎入局”(Choices: Welcome Aboard) 1.2 周期性现象(Periodic phenomena) 1.2.1 时间和空间(time and space) 1.2.1.1 时间和空间周期性在波动中最自然地结合在一起 1.2.1.2 更多关于空间的周期性例子 1.2.2 定义&…

11 简单的Thymeleaf语法

11.1 spring-boot环境准备 重要依赖&#xff1a; <!--thymeleaf--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 11.2 转发消息不转义 就是如…