MongoDB权威指南(4)- 索引
jopen
13年前
<p style="margin:5px auto;">Note:mongoDB的索引的工作方式和关系数据库中的索引几乎是一样的。</p> <p style="margin:5px auto;"><strong>1.索引简介</strong></p> <p style="margin:5px auto;">假设我们要按单个key查询,如下:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">mark</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">对单个的key进行查询的时候,我们可以在这个key上建立索引来提高查询速度。使用ensureIndex方法建立索引如下:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">一个索引只需创建一次,重复创建相同的索引没有任何效果。</p> <p style="margin:5px auto;">一个key上建立的索引会使对这个key的查询速度提高,除此之外就没有效果了,即使是查询包含这个key,如:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">date</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : date1}).sort({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">date</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">这个查询里,服务器必须遍历整个collction来找到日期符合的记录,这个过程叫做table scan(全表扫描),一般情况下你都会尽量避免</p> <p style="margin:5px auto;">table scan,因为它对大型的collection运行非常缓慢。作为一条经验规则,你需要给它创建一个索引,包含了查询中用到的所有key的一个索引。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">date</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">传递给ensureIndex方法的document参数和sort方法的参数是一样的,它是一组key/value对,值可能是1或-1,代表索引进行的方向。</p> <p style="margin:5px auto;">如果索引里只有一个key,方向就无所谓了,如果索引里有多个key,那么你就得考虑索引的方向问题。假设我们有下边的一些用户:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">{ </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">smith</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">48</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">0</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">smith</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">john</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">36</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">2</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">john</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">18</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">3</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">joe</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">36</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">4</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">john</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">7</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">5</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">simon</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">3</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">6</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">joe</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">27</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">7</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">jacob</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">17</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">8</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">52</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">9</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">simon</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">59</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;"> }</span> </div> </div> <p style="margin:5px auto;">如果我们建立索引{"username" : 1, "age" : -1},mongoDB就会按下边的样子组织用户:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">{ </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">jacob</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">17</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">8</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">joe</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">36</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">4</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">joe</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">27</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">7</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">john</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">36</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">2</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">john</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">18</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">3</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">john</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">7</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">5</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">52</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">9</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">simon</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">59</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">simon</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">3</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">6</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">smith</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">48</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">0</span> <span style="line-height:1.5;"> }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ..., </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">smith</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">user_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;"> }</span> </div> </div> <p style="margin:5px auto;">首先按名字的升序排列,名字相同的组里按降序排列。这索引会优化按{"username" : 1, "age" :-1}的排序操作,而对{"username" : 1, "age" : 1}</p> <p style="margin:5px auto;">的排序效果就没那么好了,如果我们想优化{"username" : 1, "age" : 1},那就应该按{"username" : 1, "age" : 1}来建立索引,让年龄也升序排列。</p> <p style="margin:5px auto;">对username和age建立的索引同时也会是对username的查询速度提高,通常,如果索引有N个key组成,对其中前边部分的查询速度也会提高。</p> <p style="margin:5px auto;">例如,我们建立了索引{"a" : 1, "b" : 1, "c" : 1, ..., "z" : 1},那么效果上相当于我们也有了{"a" : 1}, {"a" : 1, "b" : 1}, {"a" : 1, "b" : 1, "c" :1}等等。</p> <p style="margin:5px auto;">mongoDB的查询优化器会调整查询条件之间的顺序以利用索引,比如说你要查询{"x" : "foo", "y" : "bar"},而你的索引是{"y" : 1, "x" :1},优化器会自行调整。</p> <p style="margin:5px auto;">索引的不利之处是给插入、更新、删除操作增添了一些负担。</p> <p style="margin:5px auto;">在某些情况下,使用索引也许还不如不用索引。通常,如果查询返回collection里一半甚至更多的记录,那么相比为几乎每个document查找索引及其值,直接使用</p> <p style="margin:5px auto;">全表扫描还更快些。</p> <p style="margin:5px auto;"><em>索引度量? (Scaling Index)</em></p> <p style="margin:5px auto;">假设我们有个collection存储用户的状态消息,我们想按用户查询每个用户的最新状态,根据我们学到的知识,我们可能会这样建立索引:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.status.ensureIndex({user : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">, date : </span> <span style="line-height:1.5;">-</span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">这个索引会使对user和date的查询速度提高,但实际上并不是最好的选择。按照这个索引,我们的数据可能是下边这个样子:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">User </span> <span style="line-height:1.5;">123</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">13</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> User </span> <span style="line-height:1.5;">123</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">12</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> User </span> <span style="line-height:1.5;">123</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">11</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> User </span> <span style="line-height:1.5;">123</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">5</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> User </span> <span style="line-height:1.5;">123</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">4</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> User </span> <span style="line-height:1.5;">124</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">12</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> User </span> <span style="line-height:1.5;">124</span> <span style="line-height:1.5;"> on March </span> <span style="line-height:1.5;">11</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">2010</span> <span style="line-height:1.5;"><br /> ...</span> </div> </div> <p style="margin:5px auto;">如果只是这个数据规模,这样子看起来还是不错的,如果程序里有百万千万的用户,每个用户每天都会产生几十条状态更新呢?</p> <p style="margin:5px auto;">如果每个用户的状态消息的索引记录都占用了磁盘空间一页的大小,那么每次进行最新状态查询时,数据都不得不加载另外一个页面进内存。</p> <p style="margin:5px auto;">要是我们使用{date : -1, user : 1}做索引,那么数据库就可以将最近几天的索引保持在内存里,会有更少的页面对换,查询最新状态</p> <p style="margin:5px auto;">也会更快。</p> <p style="margin:5px auto;"><em>对嵌入document的key建立索引</em></p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.blog.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">comments.date</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">对嵌入的document建立索引和对顶级document建立索引没有差别,两者在组合索引里也可以组合使用。</p> <p style="margin:5px auto;"><em>为排序建立索引</em></p> <p style="margin:5px auto;">如果对一个未建立索引的key调用sort方法,mongoDB需要取出所有的数据,放入内存然后排序,所以这个大小是有限制的,</p> <p style="margin:5px auto;">如果collection太大,mongoDB就会返回一个错误。建立索引可以避免这个问题,使你可以对任意数量的数据进行排序而不会耗尽内存。</p> <p style="margin:5px auto;"><strong>2.唯一索引</strong><em> </em></p> <p style="margin:5px auto;">唯一索引保证对于指定的key,collection里每个document中其值都是唯一的。如,要保证用户名都不重复:</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">}, {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">unique</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;color:#0000ff;">true</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">Note:如果key不存在,索引就会将其值存储为null,如果要再插入一个不含此key的document,插入就会失败,因为已经有了一个</p> <p style="margin:5px auto;">值为null的document。</p> <p style="margin:5px auto;"><em>删除重复</em></p> <p style="margin:5px auto;">对已有的collection建立唯一索引时,里边也许已经有了重复的值,这会导致索引建立失败,如果你想删掉具有重复值的document,</p> <p style="margin:5px auto;">可以使用dropDups选项,遇到的第一个document被保留,其他的都被删除掉了。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">}, {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">unique</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;color:#0000ff;">true</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">dropDups</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;color:#0000ff;">true</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;"><em>组合唯一索引</em></p> <p style="margin:5px auto;">组合唯一索引里的单个key的值可以是重复的,但是所有key的组合必须是唯一的。</p> <p style="margin:5px auto;"><strong>3.使用explain和hint</strong></p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.foo.find().explain()</span> </div> </div> <p style="margin:5px auto;">explain方法返回一个document而不是游标本身,这个document包含了用到的索引、统计信息等。</p> <p style="margin:5px auto;">举个例子,对一个无索引的collection执行一个最简单的查询({}),返回64个document,那么explain的输出为</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.find().explain()<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BasicCursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [ ],<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscanned</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">64</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscannedObjects</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">64</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">n</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">64</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">millis</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">0</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">allPlans</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BasicCursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [ ]<br /> }<br /> ]<br /> </span> <br /> <span style="line-height:1.5;">}<br /> </span> </div> </div> <ul style="margin-left:45px;"> <li><pre style="margin-top:0px;word-wrap:break-word;white-space:pre-wrap;margin-bottom:0px;"><span style="line-height:19px;">"</span><span style="line-height:19px;">cursor</span><span style="line-height:19px;">"</span><span style="line-height:19px;"> : </span><span style="line-height:19px;">"</span><span style="line-height:19px;">BasicCursor</span><span style="line-height:19px;">" 意思是查询没有使用索引</span></pre></li> <li>"nscanned" : 64<br /> 数据库扫描过的document数量</li> <li><span style="line-height:19px;">"</span><span style="line-height:19px;">n</span><span style="line-height:19px;">"</span><span style="line-height:19px;"> : </span><span style="line-height:19px;">64<br /> 返回的结果集的document数量</span></li> <li><span style="line-height:19px;">"</span><span style="line-height:19px;">millis</span><span style="line-height:19px;">"</span><span style="line-height:19px;"> : </span><span style="line-height:19px;">0<br /> 数据库执行查询消耗的毫秒数</span></li> </ul> <p style="margin:5px auto;">现在我们看个稍微复杂点的例子,假设我们在age键上建立了索引,我们要查询年龄为20多岁的用户。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.c.find({age : {$gt : </span> <span style="line-height:1.5;">20</span> <span style="line-height:1.5;">, $lt : </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">}}).explain()<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> [{</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">20</span> <span style="line-height:1.5;">},{</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">}]<br /> ],<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscanned</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscannedObjects</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">12</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">n</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">12</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">millis</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">allPlans</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> [{</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">20</span> <span style="line-height:1.5;">},{</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">}]<br /> ]<br /> }<br /> ]<br /> }</span> </div> </div> <ul style="margin-left:45px;"> <li><pre style="margin-top:0px;word-wrap:break-word;white-space:pre-wrap;margin-bottom:0px;"><span style="line-height:19px;">"</span><span style="line-height:19px;">cursor</span><span style="line-height:19px;">"</span><span style="line-height:19px;"> : </span><span style="line-height:19px;">"</span><span style="line-height:19px;">BtreeCursor age_1</span><span style="line-height:19px;">" 这次不是</span>BasicCursor了,索引是存储在B-Tree的数据结构里,这个查询使用了索引,它是使用了B-Tree类型的游标。 age_1是索引的名字,有了这个名字我们就可以查询system.indexes collection,获取关于此索引的更多信息。</pre> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.system.indexes.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">ns</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">test.c</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">name</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">})<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ObjectId(</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">4c0d211478b4eaaf7fb28565</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">),<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">ns</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">test.c</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">key</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;"><br /> },<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">name</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"><br /> }</span> </div> </div> </li> <li>"allPlans" : [ ... ]<br /> 列出了此查询可用的所有的计划。如果我们有多个索引和更加复杂的查询,"allPlans"就会包含所有可能的计划。</li> </ul> <p style="margin:5px auto;">让我们看个更复杂点的查询例子,假设我们有一个索引{"username" : 1, "age" : 1}和一个索引{"age" : 1, "username" : 1},那么当我们</p> <p style="margin:5px auto;">查询username和age的时候会发生什么事?实际上这样要依赖于查询。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.c.find({age : {$gt : </span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;">}, username : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">}).explain()<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor username_1_age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;"><br /> },<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1.7976931348623157e+308</span> <span style="line-height:1.5;"><br /> }<br /> ]<br /> ],<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscanned</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">13</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscannedObjects</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">13</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">n</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">13</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">millis</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">5</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">allPlans</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor username_1_age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;"><br /> },<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">sally</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1.7976931348623157e+308</span> <span style="line-height:1.5;"><br /> }<br /> ]<br /> ]<br /> }<br /> ],<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">oldPlan</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor username_1_age_1</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> </span> [ <br /> { <br /> "username" : "sally", <br /> "age" : 10 <br /> }, <br /> { <br /> "username" : "sally", <br /> "age" : 1.7976931348623157e+308 <br /> } <br /> ] <br /> ] <br /> } <br /> } </div> </div> <p style="margin:5px auto;">由于当我们查询的是一个确定的username值和一个age范围值,所以数据库使用的是{"username" : 1, "age" : 1}这个索引,</p> <p style="margin:5px auto;">反过来,如果我们查询的是一个确定的年龄和名字范围,那么数据库就会使用另外的那个索引</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.c.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">.*</span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">}).explain()<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor age_1_username_1 multi</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">""</span> <span style="line-height:1.5;"><br /> },<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {<br /> }<br /> }<br /> ],<br /> [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">.*</span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;"><br /> },<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">.*</span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;"><br /> }<br /> ]<br /> ],<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscanned</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">2</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">nscannedObjects</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">2</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">n</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">2</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">millis</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">2</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">allPlans</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">cursor</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">BtreeCursor age_1_username_1 multi</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">indexBounds</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [<br /> [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">""</span> <span style="line-height:1.5;"><br /> },<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {<br /> }<br /> }<br /> ],<br /> [<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">.*</span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;"><br /> },<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">.*</span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;"><br /> }<br /> ]<br /> ]<br /> }<br /> ]<br /> }</span> </div> </div> <p style="margin:5px auto;">如果你发现数据库使用的不是你想用的索引,那么你可以使用hint强制数据库使用你指定的索引。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.c.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">14</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">.*</span> <span style="line-height:1.5;">/</span> <span style="line-height:1.5;">}).hint({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">age</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">指定索引通常是没有必要的,mongoDB有自己的查询优化器,会很聪明地选择使用哪个索引,你只需要关心的是优化器有可用的索引以备选择。</p> <p style="margin:5px auto;"><strong>4.索引管理</strong></p> <p style="margin:5px auto;">每个database都有个叫system.indexes的collection,它里边存储了索引的元数据信息,这个collection是保留的,不能进行插入或删除,</p> <p style="margin:5px auto;">只能通过ensureIndex和dropIndexes命令来操作里边的document。system.indexes里包含了每个索引的详细信息,另外还有个叫</p> <p style="margin:5px auto;">system.namespaces的collection列出了索引的名字。查看这collection可以看到,每个collection至少有两条记录,一个是collection本身,</p> <p style="margin:5px auto;">另外的是collection里的每个索引。</p> <p style="margin:5px auto;">建立索引是个耗时耗资源的操作,如果collection的数据量很大,你可以指定background选项来在后台进行工作。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.people.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">username</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">}, {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">background</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;color:#0000ff;">true</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">如果没有使用background选项的话,database就会阻塞所有的请求,知道索引建立完成。</p> <p style="margin:5px auto;">如果你不在需要某个索引,你可以用dropIndexes命令移除它,你可能得先在system.indexes里找到索引的名字,因为各种驱动自动生成</p> <p style="margin:5px auto;">的索引名字各不一样。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.runCommand({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">dropIndexes</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">foo</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">index</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">alphabet</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">使用*删除collection的所有的索引</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.runCommand({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">dropIndexes</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">foo</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">index</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">*</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;"></p> <p style="margin:5px auto;"><strong>5.地理空间索引</strong></p> <p style="margin:5px auto;">在ensureIndex方法中使用"2d"做参数而不是1或者-1,建立空间索引</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.map.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">gps</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">2d</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">gps这个key的值必须是某种成对的值,一个包含两个元素的数组,或者一个有两个key的嵌入的document,下边的例子都是可以的</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">{ </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">gps</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [ </span> <span style="line-height:1.5;">0</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">100</span> <span style="line-height:1.5;"> ] }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">gps</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">x</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">-</span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">y</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;"> } }<br /> { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">gps</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : { </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">latitude</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">-</span> <span style="line-height:1.5;">180</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">longitude</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">180</span> <span style="line-height:1.5;"> } }</span> </div> </div> <p style="margin:5px auto;">嵌入的document里边key的名字是任意的,它们的值缺省是从-180到180,方便使用经纬度,如果你要使用其他的单位,可以指定</p> <p style="margin:5px auto;">最大值和最小值</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.star.trek.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">light-years</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">2d</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">}, {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">min</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">-</span> <span style="line-height:1.5;">1000</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">max</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1000</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">地理空间索引可以通过两种方式来使用,一是普通的find查询,另外是作为数据库命令。</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;"> </span>> db.map.find({"gps" : {"$near" : [40, -73]}}).limit(10) </div> </div> <p style="margin:5px auto;">和下边的使用geoNear命令进行的查询等价</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.runCommand({geoNear : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">map</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, near : [</span> <span style="line-height:1.5;">40</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">-</span> <span style="line-height:1.5;">73</span> <span style="line-height:1.5;">], num : </span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;">});</span> </div> </div> <p style="margin:5px auto;">mongoDB还允许你使用一个shape来查找document,为了查找shape里所有的点,我们可以使用"$within"条件操作符,使用"$box"</p> <p style="margin:5px auto;">定义一个矩形</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.map.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">gps</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">$within</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">$box</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [[</span> <span style="line-height:1.5;">10</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">20</span> <span style="line-height:1.5;">], [</span> <span style="line-height:1.5;">15</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">]]}}})</span> </div> </div> <p style="margin:5px auto;">"$box"的值是含两个元素的数组,第一个是左边的Y值小的顶点,第二个是右边的Y值大的顶点。(大概就是这个意思,因为一般地理坐标系统</p> <p style="margin:5px auto;">中,Y轴是向上的,而我们的屏幕坐标中,原点在左上角,Y轴是向下的,数据库里仅仅是数据)</p> <p style="margin:5px auto;">同样,你也可以找到一个圆里边的所有点,$center的第一个元素是圆心,第二个元素是半径</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.map.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">gps</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">$within</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">$center</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [[</span> <span style="line-height:1.5;">12</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">25</span> <span style="line-height:1.5;">], </span> <span style="line-height:1.5;">5</span> <span style="line-height:1.5;">]}}})</span> </div> </div> <p style="margin:5px auto;">组合空间索引</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.ensureIndex({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">location</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">2d</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">desc</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">})</span> </div> </div> <p style="margin:5px auto;">如果你要查询最近的咖啡馆</p> <div style="border-bottom:#cccccc 1px solid;border-left:#cccccc 1px solid;padding-bottom:5px;overflow-x:auto;overflow-y:auto;background-color:#f5f5f5;padding-left:5px;padding-right:5px;font-family:'Courier New';font-size:12px;word-break:break-all;border-top:#cccccc 1px solid;border-right:#cccccc 1px solid;padding-top:5px;" class="cnblogs_code"> <div> <span style="line-height:1.5;">></span> <span style="line-height:1.5;"> db.map.find({</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">location</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : {</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">$near</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [</span> <span style="line-height:1.5;">-</span> <span style="line-height:1.5;">70</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">30</span> <span style="line-height:1.5;">]}, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">desc</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">coffeeshop</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">}).limit(</span> <span style="line-height:1.5;">1</span> <span style="line-height:1.5;">)<br /> {<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">_id</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : ObjectId(</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">4c0d1348928a815a720a0000</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">),<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">name</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">Mud</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">,<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">location</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [x, y],<br /> </span> <span style="line-height:1.5;"> "</span> <span style="line-height:1.5;">desc</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;"> : [</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">coffee</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">coffeeshop</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">muffins</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">, </span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">espresso</span> <span style="line-height:1.5;">"</span> <span style="line-height:1.5;">]<br /> }</span> </div> </div>