zoukankan      html  css  js  c++  java
  • nodejs 使用 mongoose 库连接 MongoDB 之查询篇

    查询方法

    mongoose查询使用最基础的方法就是find、findOne方法,前者查询所有满足条件的值,后者取满足条件的某一个值。

    查询条件

    mongoose查询条件其实就是在find方法的基础上添加mongodb条件操作符,如Thing.find().gt('age', 21)就等同于Thing.find({age: {$gt: 21}}),mongodb条件操作符如下:

    $or             或关系
    $nor            或关系取反
    $gt             大于
    $gte            大于等于
    $lt             小于
    $lte            小于等于
    $ne             不等于
    $in             在多个值范围内
    $nin            不在多个值范围内
    $all            匹配数组中多个值
    $regex          正则,用于模糊查询
    $size           匹配数组大小
    $maxDistance    范围查询,距离(基于LBS)
    $mod            取模运算
    $near           邻域查询,查询附近的位置(基于LBS)
    $exists         字段是否存在
    $elemMatch      匹配内数组内的元素
    $within         范围查询(基于LBS)
    $box            范围查询,矩形范围(基于LBS)
    $center         范围醒询,圆形范围(基于LBS)
    $centerSphere   范围查询,球形范围(基于LBS)
    $slice          查询字段集合中的元素(比如从第几个之后,第N到第M个元素)

    一些例子

    // 下面2个示例等效
    // With a JSON doc
    Person.
      find({
        occupation: /host/,
        'name.last': 'Ghost',
        age: { $gt: 17, $lt: 66 },
        likes: { $in: ['vaporizing', 'talking'] }
      }).
      limit(10).
      sort({ occupation: -1 }).
      select({ name: 1, occupation: 1 }).
      exec(callback);
    
    // Using query builder
    Person.
      find({ occupation: /host/ }).
      where('name.last').equals('Ghost').
      where('age').gt(17).lt(66).
      where('likes').in(['vaporizing', 'talking']).
      limit(10).
      sort('-occupation').
      select('name occupation').
      exec(callback);
    // 获取 "col" 集合中 "likes" 大于 100 的数据:
    db.col.find({likes : {$gt : 100}})
    
    //类似于SQL语句:
    Select * from col where likes > 100;
    // 获取"col"集合中 "likes" 大于等于 100 的数据:
    db.col.find({likes : {$gte : 100}})
    
    //类似于SQL语句:
    Select * from col where likes >=100;
    // 获取"col"集合中 "likes" 大于100,小于 200 的数据:
    db.col.find({likes : {$lt :200, $gt : 100}})
    
    // 类似于SQL语句:
    Select * from col where likes>100 AND  likes<200;
    // find() 方法传入多个键(key),以逗号隔开,类似SQL 的 AND 条件
    db.col.find({key1:value1, key2:value2})
    
    // 或者使用 $or
    db.col.find({
          $or: [
             {key1: value1}, {key2:value2}
          ]
       })
    
    // 联合使用,类似 SQL : 'where key1>value1 and (key2 = value2 or key3 = value3)'
    db.col.find({key1: {$gt:value1}, $or: [{key2: value2},{key3: value3}]})
    // 存在 age 字段(false 不存在)
    db.col.find({age:{$exists:true}});
    
    // 查询 null 值;会查询出 age 为 null 和不存在 age 字段的结果
    db.col.find({age:null})
    // 配合 exists
    db.col.find({age:{"$in":[null],"$exists":true}});
    
    // 查询age取模5等于3的记录
    db.col.find({age:{$mod:[5,3]}});
    // age不等于20的记录
    db.col.find({age:{$ne:20}});
    
    // 查询age不等于20,21,22的记录
    db.col.find({age:{$nin:[20,21,22]}});
    
    // 跳过3条记录查询其余记录的最前面5条
    db.col.find().skip(3).limit(5);
    
    // age升序排列 -1 为降序
    db.col.find().sort({age:1})

      

    填充对象

    查询对象时,对象中存在其他对象的引用,查询出来的引用对象默认是显示引用对象的id,如果需要引用对象的其他属性就需要使用populate方法填充引用对象。

    查询实例

    schema.js

    let mongoose = require('mongoose')
    let Schema = mongoose.Schema
    
    let UserSchema = new Schema({
      name: { type: String, unique: true },
      posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }]
    })
    let User = mongoose.model('User', UserSchema)
    
    let PostSchema = new Schema({
      poster: { type: Schema.Types.ObjectId, ref: 'User' },
      comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }],
      title: String,
      content: String
    })
    let Post = mongoose.model('Post', PostSchema)
    
    let CommentSchema = new Schema({
      post: { type: Schema.Types.ObjectId, ref: 'Post' },
      commenter: { type: Schema.Types.ObjectId, ref: 'User' },
      content: {
        main: String,
        label: String
      },
      points: [(point: [{ type: Schema.Types.ObjectId, ref: 'Point' }])]
    })
    let Comment = mongoose.model('Comment', CommentSchema)
    
    let PointSchema = new mongoose.Schema({
      name: String,
      parent: { type: Schema.Types.ObjectId, ref: 'point' },
      children: [{ type: Schema.Types.ObjectId, ref: 'point' }]
    })
    let Point = mongoose.model('Point', PointSchema)
    1、深层属性查询

    有些对象结构比较复杂,属性可能存在多层嵌套关系,有时需要通过对象属性下属的属性查询对象,如通过content的label的值查询Comment

    Comment.find({'content.label': value}, function (err, comment) {
        console.log(comment)
    })

    2、二维数组查询

    如果二维数组结构为[[]],这样的数组是可以查询,但是填充数组里对象时会有问题

    Comment.find({'points': value}).populate('points').exec(function (err, comment) {
        console.log(comment) // 无法填充points
    })

    所以需要填充二维数组里的对象时,不能使用这种结构,而应该如schema.js中一样,将里面的数组先作为对象保存

    Comment.find({'points': value}).populate('points.point').exec(function (err, comment) {
        console.log(comment) // 无法填充points
    })

    3、循环填充

    结构如Point,读取point时,需要填充children,而childern的childern也需要填充,使用populate只能填充当前的childern,在schema.js添加:

    PointSchema.pre('find', function(next) {
      this.populate('children')
      next()
    })

    这样每次查询时,自动为point填充children

    4、多表联合查询

    mongoose其实没有多表联合查询的方法,不过我们可以通过多次查询来实现。
    通过user的name、post的content查询post:

    User.find({name: name}, function (err, users) {
        Post.find({poster: {$in: users}, content: content}, function (err, posts) {
            console.log(posts)
        })
    })

    有时我们也需要对取出来的数据进行再次过滤,而不是通过查询语句查询
    通过user的name、post的content、comment的content.main查询post:

    let Point = mongoose.model('Point', PointSchema)
    User.find({name: name}, function (err, users) {
      Post.find({poster: {$in: users}, content: content}).populate('commenter').exec(function (err, posts) {
        posts.filter(function(post) {
          return post.commenter.content.main === value
        })
      })
    })
  • 相关阅读:
    程序跳过UAC研究及实现思路(两种方法,现在可能都不行了)
    getch(),getche(),getchar()的区别
    命令行版扫雷(vc08)
    类成员函数指针的特殊之处(成员函数指针不是指针,内含一个结构体,需要存储更多的信息才能知道自己是否virtual函数)
    WCF与Web API 区别
    扩展方法库
    开源Dubbox
    AngularJs应用页面
    浅谈可扩展性框架:MEF
    AngularJs + ASP.NET MVC
  • 原文地址:https://www.cnblogs.com/jiayouba/p/14989331.html
Copyright © 2011-2022 走看看