04月08, 2018

mongdb 的查询语句

mongdb 的查询语句

官方文档

表结构

{
    "_id" : ObjectId("5ac32a192e9d816838f3baae"),
    "name" : "2017年高分获奖剧情《魅影缝匠》BD中英双字幕",
    "url" : "http://www.dytt8.net/html/gndy/dyzz/20180328/56582.html",
    "date" : "2018-03-28 10:21:11",
    "content" : "电影剧情介绍"
    "image" : "http://www.imageto.org/images/kj9Ny.jpg",
    "ftp" : "ftp://ygdy8:ygdy8@yg45.dydytt.net:7166/阳光电影www.ygdy8.com.魅影缝匠.BD.720p.中英双字幕.mkv",
    "magnet" : "magnet:?xt=urn:btih:cf732c5fec17fc42505daa2effc3e12a74412d05&dn=%e9%98%b3%e5%85%89%e7%94%b5%e5%bd%b1www.ygdy8.com.%e9%ad%85%e5%bd%b1%e7%bc%9d%e5%8c%a0.BD.720p.%e4%b8%ad%e8%8b%b1%e5%8f%8c%e5%ad%97%e5%b9%95.mkv&tr=udp%3a%2f%2ftracker.leechers-paradise.org%3a6969%2fannounce&tr=udp%3a%2f%2feddie4.nl%3a6969%2fannounce&tr=udp%3a%2f%2fshadowshq.eddie4.nl%3a6969%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce"
}

基础查询

查询全部

db.getCollection('movie').find({})

排序

//正序
db.getCollection('movie').find({}).sort({date:1})

//反序
db.getCollection('movie').find({}).sort({date:-1})

分页

//查询前十个
db.getCollection('movie').find({}).limit(10)

//查询全部,跳过前10个
db.getCollection('movie').find({}).skip(10)

//跳过前10个,查询第11到20个元素
db.getCollection('movie').find({}).skip(10).limit(10)
db.getCollection('movie').find({}).limit(10).skip(10)

条件查询

// 等于
db.getCollection('movie').find({name:"2018年喜剧《祖宗十九代》HD国语中字"})

//不等于
db.getCollection('movie')
    .find({
        name:{
            $ne : "2018年喜剧《祖宗十九代》HD国语中字"
        }
    })

// 大于
db.getCollection('movie')
    .find({
        date:{
            $gt : "2018-03-27"
        }
    })

// 大于等于
db.getCollection('movie')
    .find({
        date:{
            $gte : "2018-03-27 11:13:30"
        }
    })

// 小于
db.getCollection('movie')
    .find({
        date:{
            $lt : "2018-03-27"
        }
    })

// 小于等于
db.getCollection('movie')
    .find({
        date:{
            $lte : "2018-03-27 11:13:30"
        }
    })

多条件查询

// 和 AND  name=v1 and url = v2
db.getCollection('movie').find({
    name:"09最新惊悚大片《地铁惊魂/骑劫地下铁》R5中字",
    url:"http://www.dytt8.net/html/gndy/dyzz/20091004/22009.html"
})

//或 OR  name=v1 or name = v2
db.getCollection('movie').find({
        $or:[
           {name:"09最新惊悚大片《地铁惊魂/骑劫地下铁》R5中字"},
           {name:"09最新爱情片《乱青春》DVD中字"}
        ]
    })

//联合使用  date >= v1 and date <= v2 and (name=v3 or name=v4)
db.getCollection('movie').find({        
    date:{
       $gte:"2009-10-04 00:00:00"
    },
    date:{
       $lte:"2009-10-05 13:07:37"
    },
    $or:[
           {name:"09最新惊悚大片《地铁惊魂/骑劫地下铁》R5中字"},
           {name:"09最新爱情片《乱青春》DVD中字"}
    ]
})

$type

\$type操作符是基于BSON类型来检索集合中匹配的数据类型,并返回结果。 \$type的类型

//查询  magnet类型为 ‘String’ 类型的记录(不包括magnet:null)
db.getCollection('movie').find({magnet : {$type : 2}})

索引

// 建立ensureIndex的正序唯一索引
db.getCollection('movie').ensureIndex({url:1},{unique:true})

// 返回
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1.0
}

ensureIndex() 接收可选参数,可选参数列表如下:

参数 值类型 描述
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDups Boolean 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
v index version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.

聚合 aggregate()

$project 修改文档

$project对象中对应的属性值为1时代表显示,为0时代表隐藏。 管道操作中有大量的操作符号,这些操作符的作用就如同mysql中的函数。 聚合管道操作符(Aggregation Pipeline Operators)

// 相当于mysql select name,url,date,'' as 'col_temp'
db.getCollection('movie').aggregate([
    {
        $project  : {
            _id : 0, //隐藏 _id 列
            name : 1, //显示 name 列
            url : 1,
            date: 1,
            col_temp : '' // 伪劣,占位
        }
    }
]);

// 相当于mysql select name,url,SUBSTR(date,0,10)
db.getCollection('movie').aggregate([
    {
        $project  : {
            _id : 0,
            name : 1,
            url : 1,
            date: { $substr: [ "$date", 0, 10 ] },
        }
    }
]);

$match 匹配文档

$match使用MongoDB的标准查询操作。然后配出所有符合条件的文档。

// 相当于 where date> "2018-01-01" and date < "2018-04-01"
db.getCollection('movie').aggregate([
    {
        $match :{
            date : {$gt : "2018-01-01",$lt : "2018-04-01"}
        }
    }
]);

$group 文档分组

$group类似与MySQl的group by,对文档分组之后我们也可以经行一些统计工作,比如求和$sum,求最大值$max,最小值$min,平均值$avg等等,具体参考聚合管道操作符(Aggregation Pipeline Operators)。 使用$group时必须要指定_id字段

// 统计每天发布的电影数量
db.getCollection('movie').aggregate([
    {
        $group :{
            _id : { $substr: [ "$date", 0, 10 ] },
            count : {$sum : 1}
        }
    }
]);

$unwind 列拆分

$unwind将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。就是把多对一拆成一对一。比如{name:zhangsan,script:['java','javascript']}拆分成两条记录{name:zhangsan,script:'java'}和{name:zhangsan,script:'javascript'}

//把含有多张图片的电影拆成一个图片一个电影
db.getCollection('movie').aggregate([
    {
        $match : {
            image : {
                $type:4
            }
        }
    },
    {
        $unwind : '$image'
    }
]);

$lookup 多表查询

$lookup提供了类似SQL中的多表关联查询的功能,但是又有些不同。$lookup是把整个副表所有的字段放到主表的文档中。

SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (SELECT <documents as determined from the pipeline> FROM <collection to join>  WHERE <pipeline> );
//把 movie 文档放到 movie_log 文档的 movie_obj 属性中
db.getCollection('movie_log').aggregate([
    {
        $lookup : {
           from: "movie", //副表
           localField: "movie_id", // 主表关联字段(等于foreignField的字段)
           foreignField: "movie_id", // 附表关联字段(等于localField的字段)
           as: "movie_obj" //字段别名(整个movie文档) 数组类型
       }
    }
]);

返回结果

{
    "_id": ObjectId("5acae230a782ba2d7c60568a"),
    "movie_id": "22009",
    "html": "html文档",
    "url": "http://www.dytt8.net/html/gndy/dyzz/20091004/22009.html",
    "create_time": ISODate("2018-04-09T03:46:56.565Z"),
    "movie_objs": [{
            "_id": ObjectId("5acae231a782ba2d7c60568b"),
            "name": "09最新惊悚大片《地铁惊魂/骑劫地下铁》R5中字",
            "url": "http://www.dytt8.net/html/gndy/dyzz/20091004/22009.html",
            "date": "2009-10-04 00:00:19",
            "content": "剧情说明",
            "image": [
                "http://mat1.qq.com/datalib_img/movie/pic/lib/2009-06-02/2009060215045631893923.jpg",
                "http://mat1.qq.com/datalib_img/movie/pic/lib/2009-06-02/2009060215045631893923.jpg",
                "http://mat1.qq.com/datalib_img/movie/pic/lib/2009-06-02/2009060215045631893923.jpg"
            ],
            "ftp": "ftp://dygod1:dygod1@d122.dygod.cn:1381/地铁惊魂/[电影天堂www.dygod.com]地铁惊魂.rmvb",
            "magnet": null,
            "movie_id": "22009"
        }
    ]
}

多个管道过滤

聚合函数还有其他很多功能,这里不一一介绍,参照管道操作的官方文档 MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

//按日期分组统计每天发布的电影数量,并按电影数量的倒叙排序
db.getCollection('movie').aggregate([
    {
         $project  : {
            _id : 0,
            name : 1,
            url : 1,
            date: { $substr: [ "$date", 0, 10 ] },
         }
     },
     {
          $group :{
            _id : '$date',
            count : {$sum : 1}
          }
     },
     {
         $sort : {
            count : -1
         }
     }
]);

MapReduce 命令

Map-Reduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。MongoDB提供的Map-Reduce非常灵活,对于大规模数据分析也相当实用。 Map-Reduce是通过根据指定的属性把当前集合中满足条件的数据经行分组处理,并输出到指定的一个集合中。

//把满足query,sort,limit的movie按天分组,并放到movie_count_by_dat集合中。
db.getCollection('movie').mapReduce(
    function(){emit(this.date.substr(0,10),1)},
    function(key, values) {return Array.sum(values)},
    {
        query : {
            date : {$gt:'2018-01-01'}
        },
        out : 'movie_count_by_dat',
        sort : {
            date: -1
        },
        limit : 10
    }
);

执行上叙语句,会发现当前数据库下会多了一个movie_count_by_dat集合,这个集合里边便符合我们要求的数据,也可以直接在mapReduce()直接调用find()来显示数据。多次执行,movie_count_by_dat也不会插入重复数据。

参考【菜鸟教程】【官方文档】

本文链接:https://www.qiangshuidiyu.xin/post/mongodb.html

-- EOF --

Comments