mongodb基本使用

MongoDB

点赞,评论这块可能操作起来比较频繁,并且,这两块的内容不怎么重要,因此可以使用MongoDB

什么是MongoDB

MongoDB 是一个跨平台的,面向文档的数据库(solr、Elasticsearch),是当前 NoSQL 数据库产品中最热门的一种。它介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的产品。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。比如表中表

MongoDB特点

MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它是一个面向集合的,模式自由的文档型数据库。具体特点总结如下: 

(1)面向集合存储,易于存储对象类型的数据

(2)模式自由

(3)支持动态查询

(4)支持完全索引,包含内部对象

(5)支持复制和故障恢复

(6)使用高效的二进制数据存储,包括大型对象(如视频等)

(7)自动处理碎片,以支持云计算层次的扩展性

(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++语言的驱动程序,社区中也提供了对 Erlang 及.NET 等平台的驱动程序

(9) 文件存储格式为 BSON(一种 JSON 的扩展)

MongoDB体系结构

MongoDB 的逻辑结构是一种层次结构。主要由:文档(document)、集合(collection)、数据库(database)这三部分组成的。逻辑结构是面向用户的,用户使用 MongoDB 开发应用程序使用的就是逻辑结构。

(1)MongoDB 的文档(document),相当于关系数据库中的一行记录。

(2)多个文档组成一个集合(collection),相当于关系数据库的表。

(3)多个集合(collection),逻辑上组织在一起,就是数据库(database)。

(4)一个 MongoDB 实例支持多个数据库(database)

数据类型

基本数据类型

null:用于表示空值或者不存在的字段,{“x”:null}

布尔型:布尔类型有两个值true和false,{“x”:true}

数值:mongo默认使用64为浮点型数值。{“x”:3.14}或{“x”:3}。对于整型值,可以使用NumberInt(4字节符号整数)或NumberLong(8字节符号整数),

{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}

字符串:UTF-8字符串都可以表示为字符串类型的数据,{“x”:“呵呵”}

日期:日期被存储为自新纪元依赖经过的毫秒数,不存储时区,{“x”:new Date()}

正则表达式:查询时,使用正则表达式作为限定条件,语法与JavaScript的正则表达式相同,{“x”😕[abc]/}

数组:数据列表或数据集可以表示为数组,{“x”: [“a“,“b”,”c”]}

内嵌文档:文档可以嵌套其他文档,被嵌套的文档作为值来处理,{“x”:{“y”:3 }} ,表中表

对象Id:对象id是一个12字节的字符串,是文档的唯一标识,{“_id”: objectId() }

二进制数据:二进制数据是一个任意字节的字符串。它不能直接在shell中使用。如果要将非utf-字符保存到数据库中,二进制数据是唯一的方式。

代码:查询和文档中可以包括任何JavaScript代码,{“x”:function(){/…/}}

Docker安装MongoDB

docker pull mongo
docker run -di --name=mongo -p 27017:27017 mongo

常用命令

选择和创建数据库

选择和创建数据库的语法格式:

use 数据库名称

如果数据库不存在则自动创建

插入与查询文档

插入文档的语法格式:

db.集合名称.insert({BSON格式的数据})

查询集合的语法格式:

db.集合名称.find()

查询用户id是233的数据

db.集合名称.find({userId: ‘233’})

只查询一条

db.集合名称.findOne({userId: ‘233’})

返回指定条数的记录

db.集合名称.find().limit(3)

修改与删除文档

修改文档的语法结构:

Db.集合名称.update(条件,修改后的数据)

如果我们想修改_id为1的记录,名称为张三,输入以下语句:

Db.集合名称.update({_Id:ObjectId(1)}, {name:’张三’})

执行后,我们会发现,这条文档除了name字段其它字段都不见了,为了解决这个问题,

我们需要使用修改器$set来实现,命令如下:

Db.集合名称.update({{_Id:ObjectId(1)}:1}, {$set:{name:’张三’}})

删除文档的语法结构:

Db.集合名称.remove(条件)

以下语句可以将数据全部删除,请慎用

Db.集合名称.remove({})

统计条数

统计记录条件使用count()方法

Db.集合名称.count()

Db.集合名称.count(条件)

模糊查询

MongoDB的模糊查询是通过正则表达式的方式实现的。格式为:

/字符串/

比如标题中包含java的帖子

Db.集合名称.find(title:/java/)

比如查询以“张”开头的名字

Db.集合名称.find(name: /^张/)

大于 小于 不等于 包含 不包含

大于: g t , 小 于 gt,小于 gtlt,大于等于 g t e , 小 于 等 于 gte,小于等于 gtelte,不等于 n e , 包 含 ne,包含 nein,不包含$nin

查询阅读数大于10的帖子

Db.集合名称.find({readNum:{$gt:10}})

查询评论集合中userid字段不包含1013和1014的文档

Db.集合名称.find({userId: {$nin:[‘1013’, ‘1014’]}})

条件连接

我们如果需要查询同时满足两个以上条件,需要使用$and操作符将条件进行关联。(相

当于SQL的and)

格式为:

$and:[ { },{ },{ } ]

示例:查询帖子集合中readNum大于等于1000 并且小于2000的文档

Db.集合名称.find( {KaTeX parse error: Expected '}', got 'EOF' at end of input: …d: [ {readNum:{gte:1000}}, {readNum:{$lte: 2000}} ]} )

如果两个以上条件之间是或者的关系,我们使用$or 用法和and相同

$or:[ { },{ },{ } ]

列值增长

如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用$inc运算符来实现

Db.集合名称.update({_Id:ObjectId(1)}, {$inc:{readNum:NumberInt(2)}})

在springboot项目中使用

依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
  </dependency>

yml配置

  spring:
  	data:
    	mongodb:
      	host: 121.89.192.157
      	database: blog
      	port: 27017

dao接口

@Repository
public interface CommentDao extends MongoRepository<Comment, String> {

    /**
     * 根据博客id查询
     * 根据时间降序排序
     * @param commentBlog
     * @return
     */
    List<Comment> getCommentsByCommentBlogOrderByCreatedTimeDesc(String commentBlog);

}

JPA语法

KeywordSampleJPQL snippet
AndfindByLastnameAndFirstname… where x.lastname = ?1 and x.firstname = ?2
OrfindByLastnameOrFirstname… where x.lastname = ?1 or x.firstname = ?2
Is,EqualsfindByFirstname,findByFirstnameIs,findByFirstnameEquals… where x.firstname = ?1
BetweenfindByStartDateBetween… where x.startDate between ?1 and ?2
LessThanfindByAgeLessThan… where x.age < ?1
LessThanEqualfindByAgeLessThanEqual… where x.age ⇐ ?1
GreaterThanfindByAgeGreaterThan… where x.age > ?1
GreaterThanEqualfindByAgeGreaterThanEqual… where x.age >= ?1
AfterfindByStartDateAfter… where x.startDate > ?1
BeforefindByStartDateBefore… where x.startDate < ?1
IsNullfindByAgeIsNull… where x.age is null
IsNotNull,NotNullfindByAge(Is)NotNull… where x.age not null
LikefindByFirstnameLike… where x.firstname like ?1
NotLikefindByFirstnameNotLike… where x.firstname not like ?1
StartingWithfindByFirstnameStartingWith… where x.firstname like ?1(parameter bound with appended %)
EndingWithfindByFirstnameEndingWith… where x.firstname like ?1(parameter bound with prepended %)
ContainingfindByFirstnameContaining… where x.firstname like ?1(parameter bound wrapped in%)
OrderByfindByAgeOrderByLastnameDesc… where x.age = ?1 order by x.lastname desc
NotfindByLastnameNot… where x.lastname <> ?1
InfindByAgeIn(Collection<Age> ages)… where x.age in ?1
NotInfindByAgeNotIn(Collection<Age> age)… where x.age not in ?1
TruefindByActiveTrue()… where x.active = true
FalsefindByActiveFalse()… where x.active = false
IgnoreCasefindByFirstnameIgnoreCase… where UPPER(x.firstame) = UPPER(?1)

分页查询

    @Test
    void testByPage() {


        //构造分页查询条件
        Comment comment = new Comment();
        comment.setCommentUser(1);
        Example<Comment> example = Example.of(comment);
        Pageable pageable = PageRequest.of(1, 5);
        //执行查询
        org.springframework.data.domain.Page<Comment> page1 = this.commentDao.findAll(example, pageable);
        //封装返回数据
        List<Comment> content = page1.getContent();
        content.forEach(System.out::println);
    }

Query

查询方法定义的两种方式

  1. 根据方法名来自动推测
  2. 自定义

本文介绍自定义的方式

@Query注解

Mongodb使用的是基于json的查询语句。

通过将org.springframework.data.mongodb.repository.Query批注添加到存储库查询方法,可以指定要使用的MongoDB JSON查询字符串,而不是从方法名称派生查询,如以下示例所示:

public interface PersonRepository extends MongoRepository<Person, String>

  @Query("{ 'firstname' : ?0 }")
  List<Person> findByThePersonsFirstname(String firstname);
}

占位符 ?0 是函数的参数。

注意: String类型的参数在绑定过程中会进行转义, 这意味着不能为之添加特殊的参数。

可以使用fields来设置返回的字段:

  @Query(value="{ 'firstname' : ?0 }", fields="{ 'firstname' : 1, 'lastname' : 1}")
  List<Person> findByThePersonsFirstname(String firstname);

上例中结果Person对象中只会有firstname、lastname 和id 属性 , 其他属性没有 。

在基于json的查询中使用SpEL表达式

查询串和field返回定义可以使用SpEL表达式 在运行时进行动态创建 。
表达式通过包含所有参数的数组公开方法参数。 以下查询使用[0]声明lastname的谓词值(相当于?0参数绑定):

public interface PersonRepository extends MongoRepository<Person, String>

  @Query("{'lastname': ?#{[0]} }")
  List<Person> findByQueryWithExpression(String param0);
}

当传入参数为对象时, 实例:

    @Query(value="{'name': ?#{ [0].name }}")
    public Page<RcControllJournalDo> querylikepages(RcControllJournalDo mdo, Pageable pageable);

上例等价于 where name = mdo.name .

更复杂的实例:

    /**
     * 当mdo.name为空时, 查询条件为  { "name" : { "$exists" : true } } ,即查询所有name列存在的记录(包括值为null的记录,但是对于没有name列的查询不到) ;
     * 当mdo.name不空时,查询条件为   { "name" : [0].name }
     */
    @Query(value=" { 'name': ?#{ ([0].name == null) or ([0].name.length() == 0)  ? '{$exists:true}' : [0].name } } ")
    public Page<RcControllJournalDo> querylikepages2(RcControllJournalDo mdo, Pageable pageable);

#{ ([0].name == null) or ([0].name.length() == 0) ? '{$exists:true}' : [0].name } 为SpEL表达式 (三目表达式)。

模糊查询例子:

    /**
     * 使用正则表达式模糊查询 
     */
    @Query(value=" { 'idno': ?#{ ([0].name == null) or ([0].name.length() == 0)  ? {$exists:true} : {$regex: [0].name } } } ")
    public Page<RcControllJournalDo> querylikepages21(RcControllJournalDo mdo, Pageable pageable);

mongodb的正则表达式查询语法为:

>db.posts.find({post_text:{$regex:"runoob"}})
>db.posts.find({post_text:{$regex:"runoob",$options:"$i"}}) 

例子:
根据前端上送的查询条件模糊匹配name 和idno , 当有值时查询之,无则查询所有:

    /**
     * 模糊查询name 和 idno  <br>
     * 1. mongodb or语法  :{ $or :[{}, {},...] }  例子: {$or:[{"by":"aaa"} , {"title": "bbb"}]}  , 即 where by=aaa or title=bbb <BR>
     * 2. { $or :[{'name' : ?#{}}, {'idno' : ?#{}}] }  <br>
     * 
     */
    @Query(value=" { $or :[{'name' : ?#{ ([0].name == null) or ([0].name.length() == 0)  ? '{$exists:true}' :  {$regex:[0].name} }},"
            + " {'idno' : ?#{ ([0].idno == null) or ([0].idno.length() == 0)  ? '{$exists:true}' : {$regex: [0].idno} }}] } ")
    public Page<RcControllJournalDo> querylikepages3(RcControllJournalDo mdo, Pageable pageable);

输入参数:
mdo.setName(“宋”);
mdo.setIdno(“112”);
打印的日志为:

find using query: { "$or" : [{ "name" : { "$regex" : "宋" } }, { "idno" : { "$regex" : "112" } }] }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值