欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mongodb基础知识-内嵌数组相关  

程序员文章站 2022-03-20 18:05:29
...

    前面看到mongodb文档的字段的值可以嵌套一个文档,当然字段的值也可以嵌套一个数组。不过嵌套数组就比嵌套文档稍微复杂一些,因为数组既可以是基本数据类型的数组,也可以是文档类型的数组。为了逻辑的顺畅,先从嵌套基本数据类型的数组开始,然后过度到嵌套文档的数组。

    #########################################################################

    基本数据的数组:

    1. 精确匹配  数组中值完全一样,值的顺序也一致

 

// 样例数据
{ "_id" : 1, "score" : [ -1, 3 ] }
{ "_id" : 2, "score" : [ 1, 5 ] }
{ "_id" : 3, "score" : [ 1, 5, 6 ] }
{ "_id" : 4, "score" : [ 5, 6 ] }
{ "_id" : 5, "score" : [ 5, 1 ] }

// 精确查询
db.students.find( { score: [1, 5] } )

// 匹配的只有一个
{ "_id" : 2, "score" : [ 1, 5 ] }

// 下面两个不会匹配  顺序不一样  个数不一样
{ "_id" : 5, "score" : [ 5, 1 ] }
{ "_id" : 3, "score" : [ 1, 5, 6 ] }

   2. 匹配数组单个元素  也就是数据中有一个元素等于查询的这个元素 就返回。

// 样例数据
{ "_id" : 1, "score" : [ -1, 3 ] }
{ "_id" : 2, "score" : [ 1, 5 ] }
{ "_id" : 3, "score" : [ 1, 5, 6 ] }
{ "_id" : 4, "score" : [ 5, 6 ] }
{ "_id" : 5, "score" : [ 5, 1 ] }

// 匹配数组一个元素
db.students.find( { score:  5 } )

// 返回的文档是
{ "_id" : 2, "score" : [ 1, 5 ] }// 5
{ "_id" : 3, "score" : [ 1, 5, 6 ] }// 5
{ "_id" : 4, "score" : [ 5, 6 ] }// 5
{ "_id" : 5, "score" : [ 5, 1 ] }// 5

    3. 匹配数组多个元素  也就是所有的查询条件都可以在数组中找到匹配的元素,可以是单个元素满足所有条件,也可以是多个元素-每个元素只满足一个条件。

// 样例数据
{ "_id" : 1, "score" : [ -1, 3 ] }
{ "_id" : 2, "score" : [ 1, 5 ] }
{ "_id" : 3, "score" : [ 1, 5, 6 ] }
{ "_id" : 4, "score" : [ 5, 6 ] }
{ "_id" : 5, "score" : [ 5, 1 ] }

// 每个条件都有元素可以匹配
db.students.find( { score: { $gt: 0, $lt: 2 } } )

// 返回的文档是
{ "_id" : 1, "score" : [ -1, 3 ] } // 3 -1
{ "_id" : 2, "score" : [ 1, 5 ] }// 1 1
{ "_id" : 3, "score" : [ 1, 5, 6 ] }// 1 1
{ "_id" : 5, "score" : [ 5, 1 ] }// 1 1

   4. 数组单个元素匹配多个条件 注意和上面的区别  这里指的是数组中存在至少一个元素满足所有的条件。

// 样例数据
{ "_id" : 1, "score" : [ -1, 3 ] }
{ "_id" : 2, "score" : [ 1, 5 ] }
{ "_id" : 3, "score" : [ 1, 5, 6 ] }
{ "_id" : 4, "score" : [ 5, 6 ] }
{ "_id" : 5, "score" : [ 5, 1 ] }

// 至少一个元素满足所有条件
db.students.find( { score: { $elemMatch: { $gt: 0, $lt: 2 } } } )


// 返回的文档是
{ "_id" : 2, "score" : [ 1, 5 ] }// 1
{ "_id" : 3, "score" : [ 1, 5, 6 ] }// 1
{ "_id" : 5, "score" : [ 5, 1 ] }// 1

 

   5. 建立索引

// 样例数据
{ _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] }
{ _id: 2, item: "ABC", ratings: [ 3, 8, 9 ] }

// 对ratings字段建立索引
db.survey.createIndex( { ratings: 1 } )

 

    #########################################################################

    嵌套文档的数组:

    

// 样例数据
    {
       _id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: { artist: "Picasso", food: "pizza" },
       finished: [ 17, 3 ],
       badges: [ "blue", "black" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 85, bonus: 10 }
       ]
     },
     {
       _id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: { artist: "Miro", food: "meringue" },
       finished: [ 11, 25 ],
       badges: [ "green" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 64, bonus: 12 }
       ]
     },
     {
       _id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: { artist: "Cassatt", food: "cake" },
       finished: [ 6 ],
       badges: [ "blue", "red" ],
       points: [
          { points: 81, bonus: 8 },
          { points: 55, bonus: 20 }
       ]
     },
     {
       _id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: { artist: "Chagall", food: "chocolate" },
       finished: [ 5, 11 ],
       badges: [ "red", "black" ],
       points: [
          { points: 53, bonus: 15 },
          { points: 51, bonus: 15 }
       ]
     },
     {
       _id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: { artist: "Noguchi", food: "nougat" },
       finished: [ 14, 6 ],
       badges: [ "orange" ],
       points: [
          { points: 71, bonus: 20 }
       ]
     },
     {
       _id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: { food: "pizza", artist: "Picasso" },
       finished: [ 18, 12 ],
       badges: [ "black", "blue" ],
       points: [
          { points: 78, bonus: 8 },
          { points: 57, bonus: 7 }
       ]
     }

 

    1. 组合元素满足查询条件 对于每一个条件都可以找到嵌套文档匹配

//
db.users.find( { 'points.points': { $lte: 55, "$gt": 80 } } )

//
{
   "_id" : 3,
   "name" : "ahn",
   "age" : 22,
   "type" : 2,
   "status" : "A",
   "favorites" : { "artist" : "Cassatt", "food" : "cake" },
   "finished" : [ 6 ],
   "badges" : [ "blue", "red" ],
   "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ]// 55 81
}

 

    2. 单个文档满足多个查询条件 有两种情况 一种是一个字段多个限制  一种是多个字段限制
// 第一种情况
db.users.find( { points: { $elemMatch: { points: { $lte: 70, $gte: 56}} } } )

// 返回
{
    "_id" : 2.0,
    "name" : "bob",
    "age" : 42.0,
    "type" : 1.0,
    "status" : "A",
    "favorites" : {
        "artist" : "Miro",
        "food" : "meringue"
    },
    "finished" : [ 
        11.0, 
        25.0
    ],
    "badges" : [ 
        "green"
    ],
    "points" : [ 
        {
            "points" : 85.0,
            "bonus" : 20.0
        }, 
        {
            "points" : 64.0,// 64
            "bonus" : 12.0
        }
    ]
}

{
    "_id" : 6.0,
    "name" : "abc",
    "age" : 43.0,
    "type" : 1.0,
    "status" : "A",
    "favorites" : {
        "food" : "pizza",
        "artist" : "Picasso"
    },
    "finished" : [ 
        18.0, 
        12.0
    ],
    "badges" : [ 
        "black", 
        "blue"
    ],
    "points" : [ 
        {
            "points" : 78.0,
            "bonus" : 8.0
        }, 
        {
            "points" : 57.0,// 57
            "bonus" : 7.0
        }
    ]
}
   
// 第二种情况
db.users.find( { points: { $elemMatch: { points: { $lte: 70}, bonus: 20 } } } )

// 返回
{
    "_id" : 3.0,
    "name" : "ahn",
    "age" : 22.0,
    "type" : 2.0,
    "status" : "A",
    "favorites" : {
        "artist" : "Cassatt",
        "food" : "cake"
    },
    "finished" : [ 
        6.0
    ],
    "badges" : [ 
        "blue", 
        "red"
    ],
    "points" : [ 
        {
            "points" : 81.0,
            "bonus" : 8.0
        }, 
        {
            "points" : 55.0,// 55
            "bonus" : 20.0// 20
        }
    ]
}
   3. 数组要包含某几类文档 也就有多个$elemMatch
// 意思就是说既要有文档第一个 也要有文档满足第二个
db.users.find( {"$and" : [
        { points: { $elemMatch: { points: { $lte: 70}, bonus: 20 } } },
        { points: { $elemMatch: { points: { $gt: 80}, bonus: 8 } } }
    ]} )

// 返回
{
    "_id" : 3.0,
    "name" : "ahn",
    "age" : 22.0,
    "type" : 2.0,
    "status" : "A",
    "favorites" : {
        "artist" : "Cassatt",
        "food" : "cake"
    },
    "finished" : [ 
        6.0
    ],
    "badges" : [ 
        "blue", 
        "red"
    ],
    "points" : [ 
        {
            "points" : 81.0,
            "bonus" : 8.0
        }, 
        {
            "points" : 55.0,
            "bonus" : 20.0
        }
    ]
}
 
// 也可以这么写 和上面的写法等价
db.users.find( { "points" : {"$all" : [
        { $elemMatch: { points: { $lte: 70}, bonus: 20 } },
        { $elemMatch: { points: { $gt: 80}, bonus: 8 } }
    ]}} )

// 返回
{
    "_id" : 3.0,
    "name" : "ahn",
    "age" : 22.0,
    "type" : 2.0,
    "status" : "A",
    "favorites" : {
        "artist" : "Cassatt",
        "food" : "cake"
    },
    "finished" : [ 
        6.0
    ],
    "badges" : [ 
        "blue", 
        "red"
    ],
    "points" : [ 
        {
            "points" : 81.0,
            "bonus" : 8.0
        }, 
        {
            "points" : 55.0,
            "bonus" : 20.0
        }
    ]
}