• mongodb简单用法


    修改器:

    $inc: 增加已有的键值,如果键值不存在就创建一个

    数据库中存在这样的数据:
    {
    "_id" : 0, "url": "www.example.com", "count" : 1 }
    db.fzk.update({"url" : "www.example.com"}, {"$inc" : {"count" : 1}})

    $set     :  指定一个字段的值,如果字段不存在那么就创建它,还可以修改键对应值的类型
    $unset : 将这个键可以完全删掉
    $push  : 向已有的数组的末位增加一个元素,如果没有就创建一个新的数组
    $each  : 可以一次$push 多个数据,下面向数组中放置了两个值。

    db.fzk.update(
      {"_id" : 0},
      {"$push": {"type": {"$each" : ["java", "python"]}}}
    )

    $slice : 限制数组的长度,接负整数。可以与$each搭配使用。

    db.fzk.update(
      {"_id" : 0},
      {"$push": {"top10": {"$each" : ["java", "python"], 
    "$slice" : "-10"}}} )

      如果小于10,全部保留,如果大于10,只保留最后的10个元素。$slice后跟的只能是负整数
    $ne    : 将数组作为数据集合使用,保证数组内的元素不会重复。

    db.fzk.update(
      {"namelist" : {"$ne" : "fzk" }},
      {"$push": {"namelist": "fzk"}}
    )

    $addToSet :  有些情况$ne使用不了就需要使用$addToSet $addToSet可以和$each一起使用,$ne就不可以

    db.fzk.update(
      {"_id" : 0},
      {"$addToSet": {"namelist": "fzk"}}
    )

    $pop    : 从数组的任意一端删除元素

    {$pop : { "key" : -1} }  从数组头部删除一个元素
    {$pop : { "key" : 1} }  从数组末尾删除一个元素

    $pull    : 根据特定条件删除元素

    db.lists.insert({"todo" : ["dishes", "laundry", "dry"]})
    db.lists.update({}, {"$pull" : {"todo" : "laundry"}})

    基于位置的数组修改器  : 数组下标获取 $

    db.blob.update({"post" : "post_id"}, {"$inc" : {"comments.0.votes" : 1}})
    db.blob.update({"author" : "john"}, {"$set" : {"comments.$.author" : "jim"}}) $通过匹配的进行修改

    upsert : 没有找到某个文档会创建一个新的文档,第三个参数为true表示upsert。

    db.fzk.update({}, {}, true)

    $setOnInsert : 创建的时候需要赋值,但是之后所有更新操作中,这个字段的值都不在改变。

    db.users.update({}, {"$setOnInsert" : {"createdAt" : "new Date()"}}, true)
    db.users.update({}, {"$setOnInsert" : {"createdAt" : "new Date()"}}, true) 第二次运行的时候会发现createAt字段没有改变。还是插入时候的值

    多对个文档进行修改 : 默认情况下,update只会修改一个文档,当第四个参数设置为true后,会对所有匹配的文档进行修改

    db.users.update({"_id" : 0}, {"$set" : {"gift" : "happy"}}, false, true)

    findAndMofify  : 

    ps = db.runCommend({"findAndMofify" : "processes",                 #processes 集合名
      "query" : {"status" : "READY"},                                  #query查询的条件
      "sort"    : {"priority" : -1},                                   #排序结果的条件
      "update" : {"$set" : {"status" : "RUNNING"}}                     #更新成
    })

        findAndMofify:字符串,集合名
        query:查询文档
        sort:排序结果
        update: 修改器文档
        remove:布尔类型,表示是否删除文档
        new : 布尔类型,表示返回更新前的文档还是更新后的文档,默认更新前的
        fileds : 文档中需要返回的字段
        upsert : 布尔类型,值为true表示是一个upsert,默认false
        update 和 remove 必须有一个,也只能有一个,如果没有这个命令会报错。

    消除指定的键 : find或findOne指定第二个参数指定返回的键,但是_id总是返回。可以利用 _id : 0 把_id剔除掉

    db.users.find({}, {"username" : 1, "email" : 1})
    {
      "_id" : ObjectId("4ba0f0dfd22aa494fd523620"),
      "username" : "joe",
      "email" : "joe@example.com"
    }
    db.users.find({}, {"username" : 1, "_id" : 0})
    {
      "username" : "joe",
    }

    $lt、 $lte、 $gt、 $gte分别对应<、 <=、 >、 >=

    db.users.find({"age" : {"$gte" : 18, "$lte" : 30}})

    $or $in $nin

    db.raffle.find({"ticket_no" : {"$in" : [725, 542, 390]}})
    db.raffle.find({"ticket_no" : {"$nin" : [725, 542, 390]}})
    db.raffle.find({"$or" : [{"ticket_no" : 725}, {"winner" : true}]})
    db.raffle.find({"$or" : [{"ticket_no" : {"$in" : [725, 542, 390]}}, {"winner" : true}]})

    $not $mod(取模)

    db.users.find({"id_num" : {"$mod" : [5, 1]}})             #1 6 11 16 
    db.users.find({"id_num" : {"$not" : {"$mod" : [5, 1]}}})

    null : 即会匹配本身为null的数据,又会匹配其他文档不包含这个字段的数据。用exists消除不包含的字段

    db.c.find({"z" : {"$in" : [null], "$exists" : true}})       #使用in看起来很不舒服,但是没有$eq操作符

    正则  : MongoDB使用Perl兼容的正则表达式(PCRE)库来匹配正则表达式

    db.users.find({"name" : /joe/i})      #i是正则表达式标志,可有可无
    db.foo.insert({"bar" : /baz/})     #支持正则表达式匹配,就是数据库存的就是正则表达式
    db.foo.find({"bar" : /baz/})

    数组查询

    db.food.insert({"fruit" : ["apple", "banana", "peach"]})
    db.food.find({"fruit" : "banana"})
    
    db.food.insert({"_id" : 1, "fruit" : ["apple", "banana", "peach"]})
    db.food.insert({"_id" : 2, "fruit" : ["apple", "kumquat", "orange"]})
    db.food.insert({"_id" : 3, "fruit" : ["cherry", "banana", "apple"]})
    # $all会匹配一组元素 db.food.
    find({fruit : {$all : ["apple", "banana"]}}) # _id=1 _id=3会匹配
    {fruit : {$all : [
    'apple']}和{fruit : 'apple'} #查询结果完成一样 db.food.find({"fruit" : ["apple", "banana"]}) #精确匹配,必须一致,这个不会匹配任何一条 db.food.find({"fruit.2" : "peach"}) #可以利用数组下标匹配

    $size  :  查询特定长度的数组,但是$size并不能并不能与其他查询条件(eg:$gt)组合使用

    db.food.find({"fruit" : {"$size" : 3}})

    $slice  : 

    db.blog.posts.findOne(criteria, {"comments" : {"$slice" : 10}})           #头十条
    db.blog.posts.findOne(criteria, {"comments" : {"$slice" : -10}})          #后十条
    db.blog.posts.findOne(criteria, {"comments" : {"$slice" : [23, 10]}})     #从第24条开始取到33条,不够33返回24后所有的
    
    db.blog.posts.findOne(criteria, {"comments" : {"$slice" : -1}})           #$slice 默认会返回文档的所有键   下面title和content都返回了
    结果:{
      "_id" : ObjectId("4b2d75476cc613d5ee930164"),
    "title" : "A blog post", "content" : "...", "comments" : [ { "name" : "bob", "email" : "bob@example.com", "content" : "good post." } ] }

      db.blog.posts.find({"comments.name" : "bob"}, {"comments.$" : 1})        # $操作符得到一个匹配的元素,但是这样只会返回第一个匹配的文档,如果有多条comments,只有第一条会返回
     {
      "_id" : ObjectId("4b2d75476cc613d5ee930164"),
      "comments" : [
        {
          "name" : "bob",
          "email" : "bob@example.com",
          "content" : "good post."
       }
        ]
      }

     

    数组和范围查询

    {"x" : 5}
    {"x" : 15}
    {"x" : 25}
    {"x" : [5, 25]}
    > db.test.find({"x" : {"$gt" : 10, "$lt" : 20}})      #会返回两条数据  因为5小于20,25大于10
    {"x" : 15}
    {"x" : [5, 25]}

    > db.test.find({"x" : {"$elemMatch" : {"$gt" : 10, "$lt" : 20}})    #没有结果匹配,因为15不是一个数组

    # 如果当前查询的字段上创建过索引,现在这个查询只会遍历位于10和20之间的索引,不在与5和25比较。只有当前查询的字段上建立过索引时,才可以使用ming()和max(),而且必须为这个索引的所有字段指定min和max
    > db.test.find({"x" : {"$gt" : 10, "$lt" : 20}).min({"x" : 10}).max({"x" : 20})
    {"x" : 15}

    查询内嵌文档

    {
      "name" : {
        "first" : "Joe",
        "last" : "Schmoe"
      },
      "age" : 45
    }
    > db.people.find({"name" : {"first" : "Joe", "last" : "Schmoe"}})  # 可以匹配,但是这个和顺序还有关系,如果first和last调换位置,就不能匹配
    > db.people.find({"name.first" : "Joe", "name.last" : "Schmoe"})

      > db.blog.find()
      {
        "content" : "...",
        "comments" : [
        {
          "author" : "joe",
          "score" : 3,
          "comment" : "nice post"
        },
        {
          "author" : "mary",
          "score" : 6,
          "comment" : "terrible post"
        }
        ]
      }

     > db.blog.find({"comments" : {"author" : "joe","score" : {"$gte" : 5}}})    #这种方法不对,joe会匹配第一个,$gte : 5会匹配第二个,所以返回值还是这个文档
      > db.blog.find({"comments" : {"$elemMatch" : {"author" : "joe", "score" : {"$gte" : 5}}}})      #正确写法

    $where

    > db.foo.insert({"apple" : 1, "banana" : 6, "peach" : 3})
    > db.foo.insert({"apple" : 8, "spinach" : 4, "watermelon" : 4})
    #想获取两个键具有相同值的文档
    > db.foo.find({"$where" : function () {
    ... for (var current in this) {
    ...  for (var other in this) {
    ...    if (current != other && this[current] == this[other]) {
    ...      return true;
    ...    }
    ...  }
    ... }
    ... return false;
    ... }});

      如果true,文档就作为结果集的一部分返回,如果false,就不返回。

    高级查询选项       $maxscan    $min     $max    $showDiskLoc

    > db.foo.find(criteria)._addSpecial("$maxscan", 20)  #指定扫描文档数量的上限
    > db.foo.find()._addSpecial('$showDiskLoc',true) #返回该条记录在磁盘的位置

    获取一致结果  快照(需要知道mongodb的存储过程)

    > db.foo.find().snapshot()

     唯一索引

    > db.users.ensureIndex({"username" : 1}, {"unique" : true})
    > db.people.ensureIndex({"username" : 1}, {"unique" : true, "dropDups" : true})    #dropDups在创建索引时会删除索引重复的文档,并不知道会是哪一个,慎重

    sparse :   唯一索引会把null看做值,所以无法将多个缺少唯一索引中的键的文档插入到一个集合里。sparse是这个字段可能存在可能不存在,当这个键存在时必须是唯一的

    #创建稀松索引语法   
    > db.ensureIndex({"email" : 1}, {"unique" : true, "sparse" : true}) #用unique和sparse组合可以达到如果存在这个键,键对应的值就比需是唯一的目的
    > db.ensureIndex({"email" : 1}, {"sparse" : true}) # sparse可以不是唯一的
    > db.foo.find()
    { "_id" : 0 }
    { "_id" : 1, "x" : 1 }
    { "_id" : 2, "x" : 2 }
    { "_id" : 3, "x" : 3 }

     > db.foo.find({"x" : {"$ne" : 2}})   #没有sparse index

      { "_id" : 0 }
      { "_id" : 1, "x" : 1 }
      { "_id" : 2, "x" : 2 }
      { "_id" : 3, "x" : 3 }

     > db.foo.find({"x" : {"$ne" : 2}})   #x上建了sparse index时   _id为0的没有查到  如果还想要这样的数据,需要hint()进行全盘扫描
      { "_id" : 1, "x" : 1 }
      { "_id" : 3, "x" : 3 }

    强制全盘扫描

    > db.entries.find({"created_at" : {"$lt" : hourAgo}}).hint({"$natural" : 1})

    删除索引

    db.people.dropIndex("x_1_y_1")           #是根据索引名删除
    db.people.getIndexes() #查看所有索引信息

    固定集合

    > db.createCollection("my_collection", {"capped" : true, "size" : 100000});
    > db.createCollection("my_collection2", {"capped" : true, "size" : 100000, "max" : 100}); #创建名为my_collection2的集合,大小100000字节,最多100条文档
    > db.runCommand({"convertToCapped" : "test", "size" : 10000}); #将非固定集合转为固定集合
    > db.my_collection.find().sort({"$natural" : -1}) #固定集合的自然排序就是文档的插入顺序

    TTL索引(time-to-live index)

    > db.foo.ensureIndex({"lastUpdated" : 1}, {"expireAfterSecs" : 60*60*24})                  #lastUpdated超过预计时间这条文档就删除

    聚合

    > db.articles.aggregate({"$project" : {"author" : 1}},            #将author和_id投射出来
    ... {"$group" : {"_id" : "$author", "count" : {"$sum" : 1}}},             #将_id的值设为author的值,没出现一次count +1
    ... {"$sort" : {"count" : -1}},                          # 将count降序排序
    ... {"$limit" : 5})                                 #取前五条数据

    $match  对文档进行筛选
      可与所有常规操作符连用($gt/$lt/$in等)
      用法:{$match : {"state" : "usa"}}

    $project从子文档中提取字段
      db.users.aggregate({"$project" : {"userId" : "$_id", "_id" : 0}})    #注意$_id,可以使用$fieldname代替文档中的字符值
      1.管道表达式
        最简单的是$fieldname,也可以将多个字面量组合
      2.数学表达式
        "$add" : [expr1[, expr2, ..., exprN]]      加
        "$subtract" : [expr1, expr2]            减
        "$multiply" : [expr1[, expr2, ..., exprN]]   乘
        "$divide" : [expr1, expr2]             除
        "$mod" : [expr1, expr2]               取余
      用法:    

        > db.employees.aggregate(
        ... {
        ...  "$project" : {
        ...    "totalPay" : {
        ...      "$subtract" : [{"$add" : ["$salary", "$bonus"]}, "$401k"]
        ...    }
        ...  }
        ... })

      3.日期表达式
        "$year" , "$month" , "$week" ,"$dayOfMonth" , "$dayOfWeek" , "$dayOfYear" , "$hour" , "$minute" , "$second"
        用法:

        > db.employees.aggregate(
        ... {
        ...  "$project" : {
        ...    "tenure" : {
        ...      "$subtract" : [{"$year" : new Date()}, {"$year" : "$hireDate"}]
        ...    }
        ...  }
        ... })

      4.字符串表达式
        "$substr" : [expr, startOffset, numToReturn]
        "$concat" : [expr1[, expr2, ..., exprN]]
        "$toLower" : expr
        "$toLower" : expr
        "$toUpper" : expr
        用法:一个生成 j.doe@example.com 的例子

        > db.employees.aggregate(
        ... {
        ...  "$project" : {
        ...    "email" : {
        ...      "$concat" : [
        ...        {"$substr" : ["$firstName", 0, 1]},
        ...        ".",
        ...        "$lastName",
        ...        "@example.com"
        ...      ]
        ...    }
        ...  }
        ... })

      5.逻辑表达式
        "$cmp" : [expr1, expr2]
        "$strcasecmp" : [string1, string2]
        "$eq"/"$ne"/"$gt"/"$gte"/"$lt"/"$lte" : [expr1, expr2]
        "$and" : [expr1[, expr2, ..., exprN]]
        "$or" : [expr1[, expr2, ..., exprN]]
        "$not" : expr
        "$cond" : [booleanExpr, trueExpr, falseExpr]        #booleanExpr为true就返回trueExpr,false就返回falseExpr
        "$ifNull" : [expr, replacementExpr]              #null就返回replacementExpr,否则expr

      6.一个提取的例子(老师喜欢的100分其他的 出勤10%、日常30%、期末60%)

        > db.students.aggregate(
        ... {
        ...  "$project" : {
        ...    "grade" : {
        ...      "$cond" : [
        ...        "$teachersPet",
        ...        100, // if
        ...        {// else
        ...          "$add" : [
        ...            {"$multiply" : [.1, "$attendanceAvg"]},
        ...            {"$multiply" : [.3, "$quizzAvg"]},
        ...            {"$multiply" : [.6, "$testAvg"]}
        ...          ]
        ...        }
        ...      ]
        ...    }
        ...  }
        ... })

     $group  分组

      1.分组操作符   
        可以对每个分组进行计算,比如之前的$sum

      2.算数操作符
        "$sum" 和 "$average"

      3.极值操作符
        "$max" : expr
        "$min" : expr
        "$first" : expr
        "$last" : expr

        用法:
        > db.scores.aggregate(
        ... {
        ...  "$group" : {
        ...    "_id" : "$grade",
        ...    "lowestScore" : {"$min" : "$score"},
        ...    "highestScore" : {"$max" : "$score"}
        ...  }
        ... })

      4.数组操作符
        "$addToSet" : expr
        "$push" : expr

    $unwind
      拆分,数组中的每个值拆分成单独的文档

      将comments拆分出来,取到作者为Mark的comment
      > db.blog.aggregate({"$project" : {"comments" : "$comments"}},
      ... {"$unwind" : "$comments"},
      ... {"$match" : {"comments.author" : "Mark"}})

    $sort

      > db.employees.aggregate(
      ... {
      ...  "$project" : {
      ...    "compensation" : {
      ...      "$add" : ["$salary", "$bonus"]
      ...    },
      ...    "name" : 1
      ...  }
      ... },
      ... {
      ...  "$sort" : {"compensation" : -1, "name" : 1}
      ... })

    $limit
      取前n个文档

    $skip
      跳过前n个文档

  • 相关阅读:
    MyEclipse里运行时报错
    Django中Template does not exit
    Django简单界面开发
    Django安装过程
    搭建NFS服务器和客户端过程中遇到的问题
    URL传值中文乱码的解决
    结合《需求征集系统》谈MVC框架
    对于微信小程序登录的理解图
    FpSpread基本句法
    sql,lambda,linq语句
  • 原文地址:https://www.cnblogs.com/badboyf/p/6689231.html
Copyright © 2020-2023  润新知