zoukankan      html  css  js  c++  java
  • MongoDB索引使用

    

    索引简单介绍


    MongoDB同传统数据库索引一样。相同使用的是B-tree索引。绝大多数优化MySQL/Oracle/SQLlite索引技术也相同适用于MongoDB.
    创建索引使用ensureIndex方法


    创建普通索引


    > db.users1.find()
    { "_id" : 1, "username" : "smith", "age" : 48, "user_id" : 0 }
    { "_id" : 2, "username" : "smith", "age" : 30, "user_id" : 1 }
    { "_id" : 3, "username" : "john", "age" : 36, "user_id" : 2 }
    { "_id" : 4, "username" : "john", "age" : 18, "user_id" : 3 }
    { "_id" : 5, "username" : "joe", "age" : 36, "user_id" : 4 }
    { "_id" : 6, "username" : "john", "age" : 7, "user_id" : 5 }
    { "_id" : 7, "username" : "simon", "age" : 3, "user_id" : 6 }
    { "_id" : 8, "username" : "joe", "age" : 27, "user_id" : 7 }
    { "_id" : 9, "username" : "jacob", "age" : 17, "user_id" : 8 }
    { "_id" : 10, "username" : "sally", "age" : 52, "user_id" : 9 }
    { "_id" : 11, "username" : "simon", "age" : 59, "user_id" : 10 }

    --在username字段上创建正序索引
    > db.users1.ensureIndex({"username":1})

    --对以下查询创建有效索引
    > db.people.find({"date" : date1}).sort({"date" : 1, "username" : 1})
    > db.people.ensureIndex({"date" : 1, "username" : 1})


    创建索引内嵌文档索引


    --内嵌文档例如以下
    > db.blog.posts.findOne({"comments.name":"licz"})
    {
            "_id" : ObjectId("4b2d75476cc613d5ee930164"),
            "comments" : [
                    {
                            "content" : "nice post.",
                            "date" : ISODate("2016-02-17T08:01:43.813Z"),
                            "email" : "joe@example.com",
                            "name" : "joe",
                            "visits" : 1
                    },
                    {
                            "content" : "good post.",
                            "date" : ISODate("2016-02-17T08:00:45.746Z"),
                            "email" : "bob@example.com",
                            "name" : "licz"
                    }
            ],
            "content" : "...",
            "title" : "A blog post"
    }
    > db.bolg.posts.ensureIndex({"comments.date":1})


    创建唯一索引


    > db.people.ensureIndex({"username" : 1}, {"unique" : true})


    --消除反复
    当为已有的集合中创建唯一索引时,可能一些已经反复了。这时创建索引会失败。有时可能须要把反复的文档都删掉,dropDups选项就能够保留发现的第一个文档。而删除有反复的文档。


    > db.people.ensureIndex({"username" : 1}, {"unique" : true, "dropDups" : true})


    使用explain和hint
    explain会返回查询使用索引的情况,耗时及扫描文档的统计信息。
    > db.users1.find({"username":"joe"})
    { "_id" : 5, "username" : "joe", "age" : 36, "user_id" : 4 }
    { "_id" : 8, "username" : "joe", "age" : 27, "user_id" : 7 }
    > db.users1.find({"username":"joe"}).explain()
    {
            "cursor" : "BtreeCursor username_1",
            "isMultiKey" : false,
            "n" : 2,
            "nscannedObjects" : 2,
            "nscanned" : 2,
            "nscannedObjectsAllPlans" : 2,
            "nscannedAllPlans" : 2,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 0,
            "nChunkSkips" : 0,
            "millis" : 3,
            "indexBounds" : {
                    "username" : [
                            [
                                    "joe",
                                    "joe"
                            ]
                    ]
            },
            "server" : "racdb:27017"
    }

    假设发现MongoDB使用了非预期的索引。能够使用hint强制使用某个索引。如:
    > db.c.find({"age" : 14, "username" : /.*/}).hint({"username" : 1, "age" : 1})

    和Oracle中使用hint一样。hint多数情况下是不是必需指定的。

    由于MongoDB非常智能。会替你选择选择使用如个索引。


    管理索引


    索引元信息都在system.indexes集合中
    > db.system.indexes.find()
    { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.my_collection" }
    { "v" : 1, "key" : { "x" : 1 }, "name" : "x_1", "ns" : "test.my_collection" }
    { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.people" }
    ......
    { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stocks" }
    { "v" : 1, "name" : "username_1", "key" : { "username" : 1 }, "ns" : "test.users1" }
    { "v" : 1, "name" : "_id_", "key" : { "_id" : 1 }, "ns" : "test.bolg.posts" }
    { "v" : 1, "name" : "comments.date_1", "key" : { "comments.date" : 1 }, "ns" : "test.bolg.posts" }

    --删除索引
    > db.users1.dropIndexes({"username":1})
    {
            "nIndexesWas" : 2,
            "msg" : "non-_id indexes dropped for collection",
            "ok" : 1
    }

    --或是使用runCommand命令删除索引
    > db.runCommand({"dropIndexes":"bolg.posts","index":"comments.date_1"})
    { "nIndexesWas" : 2, "ok" : 1 }

    --改动索引(重建索引)
    当原来的索引不好用时,须要重建索引,这时能够使用backgroud选项使创建过程在后台执行,这样会避免数据库产生堵塞。
    > db.users1.ensureIndex({username:1},{backgroud:true})


    地理空间索引


    另一查询变得越来越流行:要找到离当前位置近期的N个场所,如要找到给定经纬度坐标周围近期的咖啡馆。
    MongoDB为坐标平面提供了专门的索引。称作:地理空间索引
    相同能够用ensureIndex来创建,仅仅只是參数不是1或-1,而是"2d"
    db.map.ensureIndex({"gps":"2d"})
    "gps"必需是某种形式的一对值:一个包括两个元素的数组或是包括两个键的内嵌文档;键值名能够随意。例如以下:
    { "gps" : [ 0, 100 ] }
    { "gps" : { "x" : -30, "y" : 30 } }
    { "gps" : { "latitude" : -180, "longitude" : 180 } }

    默认情况下地理空间的范围是-180~180(经纬度)。要想用其他值,能够通过ensureIndex选项指定最大最小值:
    > db.star.trek.ensureIndex({"light-years" : "2d"}, {"min" : -1000, "max" : 1000})
    这样就创建了一个2000光年见方的索引。


    地理空间查询方法


    使用$near
    返回离[40, -73]近期的10个文档
    > db.map.find({"gps" : {"$near" : [40, -73]}}).limit(10)
    或是:
    > db.runCommand({geoNear : "map", near : [40, -73], num : 10});

    查找指定开头内的文档
    即将原来的$near换成$within
    $within形状參数文档(http://www.mongodb.org/display/DOCS/Geospatial+Indexing)
    矩形:使用"$box"
    > db.map.find({"gps" : {"$within" : {"$box" : [[10, 20], [15, 30]]}}})
    圆形:使用"$center"
    > db.map.find({"gps" : {"$within" : {"$center" : [[12, 25], 5]}}})



    复合地理空间索引


    应用常常要找的东西不仅仅是一个地点。比如。用户要找出周围全部的咖啡店或披萨店。将地理空间索引与普通索引组合起来就能够满足这样的需求。
    比如。要查询"location"和"desc",就能够这样创建索引:

    > db.ensureIndex({"location" : "2d", "desc" : 1})

    然后就可能非常快找到近期的咖啡馆了

    > db.map.find({"location" : {"$near" : [-70, 30]}, "desc" : "coffeeshop"}).limit(1)
    {
    "_id" : ObjectId("4c0d1348928a815a720a0000"),
    "name" : "Mud",
    "location" : [x, y],
    "desc" : ["coffee", "coffeeshop", "muffins", "espresso"]
    }

    注意:创建一个关键词组对于用户自己定义查找非常有帮助。

  • 相关阅读:
    UVA 11174 Stand in a Line,UVA 1436 Counting heaps —— (组合数的好题)
    UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)
    【Same Tree】cpp
    【Recover Binary Search Tree】cpp
    【Binary Tree Zigzag Level Order Traversal】cpp
    【Binary Tree Level Order Traversal II 】cpp
    【Binary Tree Level Order Traversal】cpp
    【Binary Tree Post order Traversal】cpp
    【Binary Tree Inorder Traversal】cpp
    【Binary Tree Preorder Traversal】cpp
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7199051.html
Copyright © 2011-2022 走看看