zoukankan      html  css  js  c++  java
  • mongoDB-索引

    先插几条数据

    db.good.insert({name:"apple",classify:{classifyId:1,classifyName:"fruit"}})
    WriteResult({ "nInserted" : 1 })
    db.good.insert({name:"banana",classify:{classifyId:1,classifyName:"fruit"}})
    WriteResult({ "nInserted" : 1 })

    ..查看

    db.good.find().pretty()
    {
        "_id" : ObjectId("5b72c435ead7a34e0b701077"),
        "name" : "apple",
        "classify" : {
            "classifyId" : 1,
            "classifyName" : "fruit"
        }
    }
    {
        "_id" : ObjectId("5b72c476ead7a34e0b701078"),
        "name" : "banana",
        "classify" : {
            "classifyId" : 1,
            "classifyName" : "fruit"
        }
    }

    ..创建简单索引(升序:1;降序:-1)

    db.good.createIndex({name:1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
    }

    explain查看是否利用了索引

    db.good.explain("executionStats").find({name:"apple"})

    还可以创建嵌入字段的索引

    db.good.createIndex({"classify.classifyId":1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 2,
        "numIndexesAfter" : 3,
        "ok" : 1
    }

    explain查看是否利用了索引

    db.good.explain("executionStats").find({"classify.classifyId":1})

    复合索引

    插入三条数据

    db.good.insert({name:"apple",price:1.5,classify:["fruit","food"]})
    db.good.insert({name:"banana",price:2,classify:["fruit","food"]})
    db.good.insert({name:"peach",price:2.5,classify:["fruit","food"]})

    创建索引

    db.good.createIndex({"name":1,"price":1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 3,
        "numIndexesAfter" : 4,
        "ok" : 1
    }

    验证

    db.good.explain("executionStats").find({name:"apple"})
    
    db.good.explain("executionStats").find({name:"apple",price: {$lt:2}})

    复合索引满足最左前缀规则

    --复合索引与排序

    1. 查询:sort({name:1,price:1})

    db.good.find().sort({name:1,price:1})
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }

    explain

    db.good.explain("executionStats").find().sort({name:1,price:1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "name" : 1,
                        "price" : 1
                    },
                    "indexName" : "name_1_price_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "name" : [
                            "[MinKey, MaxKey]"
                        ],
                        "price" : [
                            "[MinKey, MaxKey]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 5,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 6,
                "advanced" : 5,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 5,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 6,
                    "advanced" : 5,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "name" : 1,
                        "price" : 1
                    },
                    "indexName" : "name_1_price_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "name" : [
                            "[MinKey, MaxKey]"
                        ],
                        "price" : [
                            "[MinKey, MaxKey]"
                        ]
                    },
                    "keysExamined" : 5,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    2. 查询:sort({name:-1,price:-1})

    db.good.find().sort({name:-1,price:-1})
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }

    explain

    db.good.explain("executionStats").find().sort({name:-1,price:-1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "name" : 1,
                        "price" : 1
                    },
                    "indexName" : "name_1_price_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "backward",
                    "indexBounds" : {
                        "name" : [
                            "[MaxKey, MinKey]"
                        ],
                        "price" : [
                            "[MaxKey, MinKey]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 5,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 6,
                "advanced" : 5,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 5,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 6,
                    "advanced" : 5,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "name" : 1,
                        "price" : 1
                    },
                    "indexName" : "name_1_price_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "backward",
                    "indexBounds" : {
                        "name" : [
                            "[MaxKey, MinKey]"
                        ],
                        "price" : [
                            "[MaxKey, MinKey]"
                        ]
                    },
                    "keysExamined" : 5,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    3. 查询:sort({name:1,price:-1})

    db.good.find().sort({name:1,price:-1})
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }

    explain:没用到索引

    db.good.explain("executionStats").find().sort({name:1,price:-1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "SORT",
                "sortPattern" : {
                    "name" : 1,
                    "price" : -1
                },
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "direction" : "forward"
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 0,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "SORT",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 14,
                "advanced" : 5,
                "needTime" : 8,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "sortPattern" : {
                    "name" : 1,
                    "price" : -1
                },
                "memUsage" : 515,
                "memLimit" : 33554432,
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 8,
                    "advanced" : 5,
                    "needTime" : 2,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "nReturned" : 5,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 7,
                        "advanced" : 5,
                        "needTime" : 1,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "direction" : "forward",
                        "docsExamined" : 5
                    }
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    4. 查询:sort({name:-1,price:1})

    db.good.find().sort({name:-1,price:1})
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }

    explain:没用到索引

    db.good.explain("executionStats").find().sort({name:-1,price:1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "SORT",
                "sortPattern" : {
                    "name" : -1,
                    "price" : 1
                },
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "direction" : "forward"
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 0,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "SORT",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 14,
                "advanced" : 5,
                "needTime" : 8,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "sortPattern" : {
                    "name" : -1,
                    "price" : 1
                },
                "memUsage" : 515,
                "memLimit" : 33554432,
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 8,
                    "advanced" : 5,
                    "needTime" : 2,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "nReturned" : 5,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 7,
                        "advanced" : 5,
                        "needTime" : 1,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "direction" : "forward",
                        "docsExamined" : 5
                    }
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    大概可以得出结论:如果你创建的复合索引类似于{"name":1,"price":1},那么想利用索引进行sort的话,必须{"name":1,"price":1}或者{"name":-1,"price":-1},而不能是{"name":1,"price":-1},{"name":-1,"price":1}

    先删除当前索引

    db.good.dropIndex({"name":1,"price":1})
    { "nIndexesWas" : 4, "ok" : 1 }

    也可以利用索引名进行删除

    db.good.dropIndex("索引名")

    再添加一个新的

    db.good.createIndex({"name":1,"price":-1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 3,
        "numIndexesAfter" : 4,
        "ok" : 1
    }

    1. 查询:sort({name:1,price:1}),没用到索引

    db.good.find().sort({name:1,price:1})
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    db.good.explain("executionStats").find().sort({name:1,price:1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "SORT",
                "sortPattern" : {
                    "name" : 1,
                    "price" : 1
                },
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "direction" : "forward"
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 0,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "SORT",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 14,
                "advanced" : 5,
                "needTime" : 8,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "sortPattern" : {
                    "name" : 1,
                    "price" : 1
                },
                "memUsage" : 515,
                "memLimit" : 33554432,
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 8,
                    "advanced" : 5,
                    "needTime" : 2,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "nReturned" : 5,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 7,
                        "advanced" : 5,
                        "needTime" : 1,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "direction" : "forward",
                        "docsExamined" : 5
                    }
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    2. 查询:sort({name:-1,price:-1}),没用到索引.

    db.good.find().sort({name:-1,price:-1})
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    db.good.explain("executionStats").find().sort({name:-1,price:-1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "SORT",
                "sortPattern" : {
                    "name" : -1,
                    "price" : -1
                },
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "direction" : "forward"
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 0,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "SORT",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 14,
                "advanced" : 5,
                "needTime" : 8,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "sortPattern" : {
                    "name" : -1,
                    "price" : -1
                },
                "memUsage" : 515,
                "memLimit" : 33554432,
                "inputStage" : {
                    "stage" : "SORT_KEY_GENERATOR",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 8,
                    "advanced" : 5,
                    "needTime" : 2,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "inputStage" : {
                        "stage" : "COLLSCAN",
                        "nReturned" : 5,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 7,
                        "advanced" : 5,
                        "needTime" : 1,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "direction" : "forward",
                        "docsExamined" : 5
                    }
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    3. 查询:sort({name:1,price:-1}),用到了索引

    db.good.find().sort({name:1,price:-1})
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    db.good.explain("executionStats").find().sort({name:1,price:-1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "name" : 1,
                        "price" : -1
                    },
                    "indexName" : "name_1_price_-1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "name" : [
                            "[MinKey, MaxKey]"
                        ],
                        "price" : [
                            "[MaxKey, MinKey]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 5,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 6,
                "advanced" : 5,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 5,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 6,
                    "advanced" : 5,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "name" : 1,
                        "price" : -1
                    },
                    "indexName" : "name_1_price_-1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "name" : [
                            "[MinKey, MaxKey]"
                        ],
                        "price" : [
                            "[MaxKey, MinKey]"
                        ]
                    },
                    "keysExamined" : 5,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    4. 查询:sort({name:-1,price:1}),用到了索引

    db.good.find().sort({name:-1,price:1})
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c476ead7a34e0b701078"), "name" : "banana", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b72c435ead7a34e0b701077"), "name" : "apple", "classify" : { "classifyId" : 1, "classifyName" : "fruit" } }
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    db.good.explain("executionStats").find().sort({name:-1,price:1})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "name" : 1,
                        "price" : -1
                    },
                    "indexName" : "name_1_price_-1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "backward",
                    "indexBounds" : {
                        "name" : [
                            "[MaxKey, MinKey]"
                        ],
                        "price" : [
                            "[MinKey, MaxKey]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 5,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 5,
            "totalDocsExamined" : 5,
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 5,
                "executionTimeMillisEstimate" : 0,
                "works" : 6,
                "advanced" : 5,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 5,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 5,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 6,
                    "advanced" : 5,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "name" : 1,
                        "price" : -1
                    },
                    "indexName" : "name_1_price_-1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "name" : [ ],
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "backward",
                    "indexBounds" : {
                        "name" : [
                            "[MaxKey, MinKey]"
                        ],
                        "price" : [
                            "[MinKey, MaxKey]"
                        ]
                    },
                    "keysExamined" : 5,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    所以,如果你创建的复合索引类似于{"name":1,"price":-1},那么想利用索引进行sort的话,必须{"name":1,"price":-1}或者{"name":-1,"price":1},而不能是{"name":1,"price":1},{"name":-1,"price":-1}

    唯一索引

    db.good.createIndex({name:1},{unique:true})

    稀疏索引(只有包含某些索引键值的文档才会出现)

    db.good.createIndex({price:1},{unique:false,sparse:true})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 4,
        "numIndexesAfter" : 5,
        "ok" : 1
    }

    查询

    db.good.find({price:{$gt:0}})
    { "_id" : ObjectId("5b73856dead7a34e0b701079"), "name" : "apple", "price" : 1.5, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b7395edead7a34e0b70107a"), "name" : "banana", "price" : 2, "classify" : [ "fruit", "food" ] }
    { "_id" : ObjectId("5b7395f3ead7a34e0b70107b"), "name" : "peach", "price" : 2.5, "classify" : [ "fruit", "food" ] }
    db.good.explain("executionStats").find({price:{$gt:0}})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "price" : {
                    "$gt" : 0
                }
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "price" : 1
                    },
                    "indexName" : "price_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : true,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "price" : [
                            "(0.0, inf.0]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 3,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 3,
            "totalDocsExamined" : 3,
            "executionStages" : {
                "stage" : "FETCH",
                "nReturned" : 3,
                "executionTimeMillisEstimate" : 0,
                "works" : 4,
                "advanced" : 3,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 3,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 3,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 4,
                    "advanced" : 3,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "price" : 1
                    },
                    "indexName" : "price_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "price" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : true,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "price" : [
                            "(0.0, inf.0]"
                        ]
                    },
                    "keysExamined" : 3,
                    "seeks" : 1,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    查看索引大小

    db.good.totalIndexSize()
    143360

    小提示:重建索引(如果应用对数据库执行大量更新和删除操作,会产生索引碎片。碎片会导致使用更多的内存空间。而重建索引会占用写入锁)

    查看集合信息也包括了索引信息

    db.good.stats()

    多键索引(针对于数组)

    添加几条数据

    db.good.insert([{name:"apple",ratings:[5,3,10,9]},{name:"banana",ratings:[10,10,9,10]},{name:"orange",ratings:[2,7,5,9]}])
    BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 3,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
    })

    创建索引

    db.good.createIndex({ratings:1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 5,
        "numIndexesAfter" : 6,
        "ok" : 1
    }

    查询

    db.good.find({ratings:{$eq:10}})
    { "_id" : ObjectId("5b73c4f9ead7a34e0b70107c"), "name" : "apple", "ratings" : [ 5, 3, 10, 9 ] }
    { "_id" : ObjectId("5b73c4f9ead7a34e0b70107d"), "name" : "banana", "ratings" : [ 10, 10, 9, 10 ] }
    
    db.good.find({ratings:{$gte:2,$lte:5}})
    { "_id" : ObjectId("5b73c4f9ead7a34e0b70107e"), "name" : "orange", "ratings" : [ 2, 7, 5, 9 ] }
    { "_id" : ObjectId("5b73c4f9ead7a34e0b70107c"), "name" : "apple", "ratings" : [ 5, 3, 10, 9 ] }

    explain

    db.good.explain("executionStats").find({ratings:{$gte:2,$lte:5}})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "$and" : [
                    {
                        "ratings" : {
                            "$lte" : 5
                        }
                    },
                    {
                        "ratings" : {
                            "$gte" : 2
                        }
                    }
                ]
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "filter" : {
                    "ratings" : {
                        "$gte" : 2
                    }
                },
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "ratings" : 1
                    },
                    "indexName" : "ratings_1",
                    "isMultiKey" : true,
                    "multiKeyPaths" : {
                        "ratings" : [
                            "ratings"
                        ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "ratings" : [
                            "[-inf.0, 5.0]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [
                {
                    "stage" : "FETCH",
                    "filter" : {
                        "ratings" : {
                            "$lte" : 5
                        }
                    },
                    "inputStage" : {
                        "stage" : "IXSCAN",
                        "keyPattern" : {
                            "ratings" : 1
                        },
                        "indexName" : "ratings_1",
                        "isMultiKey" : true,
                        "multiKeyPaths" : {
                            "ratings" : [
                                "ratings"
                            ]
                        },
                        "isUnique" : false,
                        "isSparse" : false,
                        "isPartial" : false,
                        "indexVersion" : 2,
                        "direction" : "forward",
                        "indexBounds" : {
                            "ratings" : [
                                "[2.0, inf.0]"
                            ]
                        }
                    }
                }
            ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 2,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 4,
            "totalDocsExamined" : 2,
            "executionStages" : {
                "stage" : "FETCH",
                "filter" : {
                    "ratings" : {
                        "$gte" : 2
                    }
                },
                "nReturned" : 2,
                "executionTimeMillisEstimate" : 0,
                "works" : 6,
                "advanced" : 2,
                "needTime" : 2,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 2,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 2,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 5,
                    "advanced" : 2,
                    "needTime" : 2,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "ratings" : 1
                    },
                    "indexName" : "ratings_1",
                    "isMultiKey" : true,
                    "multiKeyPaths" : {
                        "ratings" : [
                            "ratings"
                        ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "ratings" : [
                            "[-inf.0, 5.0]"
                        ]
                    },
                    "keysExamined" : 4,
                    "seeks" : 1,
                    "dupsTested" : 4,
                    "dupsDropped" : 2,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    类比:多键索引类似于Lucene的倒排索引(数组中的元素指向对应的文档)

    多键索引的相交边界

    比如给定两个界限[3,+无穷],[-无穷,6],那么显而易见,交集是[3,6]
    对于多键索引,如果使用$elemMatch连接谓词,MongoDB可以交叉多键索引边界。

    添加数据:

    db.good.insert([{name:"AAA",ratings:[82,85,88]},{name:"BBB",ratings:[75,88,89]}])
    BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
    })

    查询

    db.good.find({ratings:{$elemMatch:{$gte:80,$lte:85}}})
    { "_id" : ObjectId("5b73d7a6ead7a34e0b701083"), "name" : "AAA", "ratings" : [ 82, 85, 88 ] }
    这个查询表示:要求数组中至少包含一个满足大于等于80,、小于等于85条件的元素,因为使用了$elemMatch,所以可以交叉边界到[80,85]
    db
    .good.find({ratings:{$gte:80,$lte:85}}) { "_id" : ObjectId("5b73d7a6ead7a34e0b701083"), "name" : "AAA", "ratings" : [ 82, 85, 88 ] } { "_id" : ObjectId("5b73d7a6ead7a34e0b701084"), "name" : "BBB", "ratings" : [ 75, 88, 89 ] } 如果不使用$elemMatch,就不会交叉边界,MongoDB不能保证它选择两种边界的哪一个 如果只有一个查询条件,那么$elemMatch不是必须的

    多键索引的复合边界

    复合边界是指对复合索引的多个键使用边界。

    添加数据:

    db.good.insert([{manager:"EEE",score:[82,85,88]},{manager:"EEE",score:[75,88,89]}])
    BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
    })

    创建索引

    db.good.createIndex({manager:1,score:1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 6,
        "numIndexesAfter" : 7,
        "ok" : 1
    }

    查询:

    db.good.find({manager: "EEE", score : { $elemMatch: { $gte: 80, $lte: 85 } }})
    { "_id" : ObjectId("5b7410edead7a34e0b701089"), "manager" : "EEE", "score" : [ 82, 85, 88 ] }
    db.good.explain("executionStats").find({manager: "EEE", score : { $elemMatch: { $gte: 80, $lte: 85 } }})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "$and" : [
                    {
                        "score" : {
                            "$elemMatch" : {
                                "$lte" : 85,
                                "$gte" : 80
                            }
                        }
                    },
                    {
                        "manager" : {
                            "$eq" : "EEE"
                        }
                    }
                ]
            },
            "winningPlan" : {
                "stage" : "FETCH",
                "filter" : {
                    "score" : {
                        "$elemMatch" : {
                            "$lte" : 85,
                            "$gte" : 80
                        }
                    }
                },
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "manager" : 1,
                        "score" : 1
                    },
                    "indexName" : "manager_1_score_1",
                    "isMultiKey" : true,
                    "multiKeyPaths" : {
                        "manager" : [ ],
                        "score" : [
                            "score"
                        ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "manager" : [
                            "["EEE", "EEE"]"
                        ],
                        "score" : [
                            "[80.0, 85.0]"
                        ]
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 1,
            "executionTimeMillis" : 11,
            "totalKeysExamined" : 2,
            "totalDocsExamined" : 1,
            "executionStages" : {
                "stage" : "FETCH",
                "filter" : {
                    "score" : {
                        "$elemMatch" : {
                            "$lte" : 85,
                            "$gte" : 80
                        }
                    }
                },
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 0,
                "works" : 3,
                "advanced" : 1,
                "needTime" : 1,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 1,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 1,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 3,
                    "advanced" : 1,
                    "needTime" : 1,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "manager" : 1,
                        "score" : 1
                    },
                    "indexName" : "manager_1_score_1",
                    "isMultiKey" : true,
                    "multiKeyPaths" : {
                        "manager" : [ ],
                        "score" : [
                            "score"
                        ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "manager" : [
                            "["EEE", "EEE"]"
                        ],
                        "score" : [
                            "[80.0, 85.0]"
                        ]
                    },
                    "keysExamined" : 2,
                    "seeks" : 1,
                    "dupsTested" : 2,
                    "dupsDropped" : 1,
                    "seenInvalidated" : 0
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    全文索引(一个集合只能有一个Text索引)

    添加数据

    db.good.insert([{manager:"admin",article:"A woman's heart is a deep ocean of secrets."},{manager:"admin",article:"I was born intelligent - education ruined me. --Bernard Shaw"}])

    创建索引

    db.good.createIndex({article:"text"})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 7,
        "numIndexesAfter" : 8,
        "ok" : 1
    }

    如果你索引所有字段:

    db.good.createIndex({"$**":"text"},{name:"my_text_index"})

    查询:

    db.good.find({$text:{$search:"woman"}})
    { "_id" : ObjectId("5b7414e5ead7a34e0b70108b"), "manager" : "admin", "article" : "A woman's heart is a deep ocean of secrets." }
    db.good.explain("executionStats").find({$text:{$search:"woman"}})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "$text" : {
                    "$search" : "woman",
                    "$language" : "english",
                    "$caseSensitive" : false,
                    "$diacriticSensitive" : false
                }
            },
            "winningPlan" : {
                "stage" : "TEXT",
                "indexPrefix" : {
                    
                },
                "indexName" : "article_text",
                "parsedTextQuery" : {
                    "terms" : [
                        "woman"
                    ],
                    "negatedTerms" : [ ],
                    "phrases" : [ ],
                    "negatedPhrases" : [ ]
                },
                "textIndexVersion" : 3,
                "inputStage" : {
                    "stage" : "TEXT_MATCH",
                    "inputStage" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                            "stage" : "OR",
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                    "_fts" : "text",
                                    "_ftsx" : 1
                                },
                                "indexName" : "article_text",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "backward",
                                "indexBounds" : {
                                    
                                }
                            }
                        }
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 1,
            "executionTimeMillis" : 0,
            "totalKeysExamined" : 1,
            "totalDocsExamined" : 1,
            "executionStages" : {
                "stage" : "TEXT",
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 0,
                "works" : 2,
                "advanced" : 1,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "indexPrefix" : {
                    
                },
                "indexName" : "article_text",
                "parsedTextQuery" : {
                    "terms" : [
                        "woman"
                    ],
                    "negatedTerms" : [ ],
                    "phrases" : [ ],
                    "negatedPhrases" : [ ]
                },
                "textIndexVersion" : 3,
                "inputStage" : {
                    "stage" : "TEXT_MATCH",
                    "nReturned" : 1,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 2,
                    "advanced" : 1,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "docsRejected" : 0,
                    "inputStage" : {
                        "stage" : "FETCH",
                        "nReturned" : 1,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 2,
                        "advanced" : 1,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "docsExamined" : 1,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                            "stage" : "OR",
                            "nReturned" : 1,
                            "executionTimeMillisEstimate" : 0,
                            "works" : 2,
                            "advanced" : 1,
                            "needTime" : 0,
                            "needYield" : 0,
                            "saveState" : 0,
                            "restoreState" : 0,
                            "isEOF" : 1,
                            "invalidates" : 0,
                            "dupsTested" : 1,
                            "dupsDropped" : 0,
                            "recordIdsForgotten" : 0,
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 1,
                                "executionTimeMillisEstimate" : 0,
                                "works" : 2,
                                "advanced" : 1,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 0,
                                "restoreState" : 0,
                                "isEOF" : 1,
                                "invalidates" : 0,
                                "keyPattern" : {
                                    "_fts" : "text",
                                    "_ftsx" : 1
                                },
                                "indexName" : "article_text",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "backward",
                                "indexBounds" : {
                                    
                                },
                                "keysExamined" : 1,
                                "seeks" : 1,
                                "dupsTested" : 1,
                                "dupsDropped" : 0,
                                "seenInvalidated" : 0
                            }
                        }
                    }
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    指定权重(这些权重表示索引字段之间的相对重要性)

    添加数据

    db.good.insertMany([{title:"God Had to Be Fair",content:"We always knew our daughter Kendall was going be a performer of some sort."},{title:"God Had to Be Fair",content:"When Kendall was five, we began to notice that she was blinking a lot and clearing her throat frequently."}])
    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("5b74da5cead7a34e0b70108d"),
            ObjectId("5b74da5cead7a34e0b70108e")
        ]
    }
    db.good.insertMany([{title:"The Doll and the White Rose",content:"I hurried into the local department store to grab1 some last minute Chirsmas gifts."},{title:"The Doll and the White Rose",content:"But I hurried the best I could through all the people to the toy department. "}])
    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("5b74da71ead7a34e0b70108f"),
            ObjectId("5b74da71ead7a34e0b701090")
        ]
    }

    创建索引

    db.good.createIndex({title:"text",content:"text"},{weights:{title:5,content:10},name:"title_content_text"})
    {
        "ok" : 0,
        "errmsg" : "Index: { v: 2, key: { _fts: "text", _ftsx: 1 }, name: "title_content_text", ns: "test.good", weights: { content: 10, title: 5 }, default_language: "english", language_override: "language", textIndexVersion: 3 } already exists with different options: { v: 2, key: { _fts: "text", _ftsx: 1 }, name: "article_text", ns: "test.good", weights: { article: 1 }, default_language: "english", language_override: "language", textIndexVersion: 3 }",
        "code" : 85,
        "codeName" : "IndexOptionsConflict"
    }
    可以看出,一个集合不允许出现多个text索引
    db.good.dropIndex("article_text")
    { "nIndexesWas" : 8, "ok" : 1 }
    db.good.createIndex({title:"text",content:"text"},{weights:{title:5,content:10},name:"title_content_text"})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 7,
        "numIndexesAfter" : 8,
        "ok" : 1
    }

    查询

    db.good.find({$text:{$search:"Kendall"}})
    { "_id" : ObjectId("5b74da5cead7a34e0b70108d"), "title" : "God Had to Be Fair", "content" : "We always knew our daughter Kendall was going be a performer of some sort." }
    { "_id" : ObjectId("5b74da5cead7a34e0b70108e"), "title" : "God Had to Be Fair", "content" : "When Kendall was five, we began to notice that she was blinking a lot and clearing her throat frequently." }
    db.good.find({$text:{$search:"God"}})
    { "_id" : ObjectId("5b74da5cead7a34e0b70108e"), "title" : "God Had to Be Fair", "content" : "When Kendall was five, we began to notice that she was blinking a lot and clearing her throat frequently." }
    { "_id" : ObjectId("5b74da5cead7a34e0b70108d"), "title" : "God Had to Be Fair", "content" : "We always knew our daughter Kendall was going be a performer of some sort." }
    db.good.find({$text:{$search:"hurried"}})
    { "_id" : ObjectId("5b74da71ead7a34e0b701090"), "title" : "The Doll and the White Rose", "content" : "But I hurried the best I could through all the people to the toy department. " }
    { "_id" : ObjectId("5b74da71ead7a34e0b70108f"), "title" : "The Doll and the White Rose", "content" : "I hurried into the local department store to grab1 some last minute Chirsmas gifts." }
    
    db.good.explain("executionStats").find({$text:{$search:"Kendall"}})
    {
        "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "test.good",
            "indexFilterSet" : false,
            "parsedQuery" : {
                "$text" : {
                    "$search" : "Kendall",
                    "$language" : "english",
                    "$caseSensitive" : false,
                    "$diacriticSensitive" : false
                }
            },
            "winningPlan" : {
                "stage" : "TEXT",
                "indexPrefix" : {
                    
                },
                "indexName" : "title_content_text",
                "parsedTextQuery" : {
                    "terms" : [
                        "kendal"
                    ],
                    "negatedTerms" : [ ],
                    "phrases" : [ ],
                    "negatedPhrases" : [ ]
                },
                "textIndexVersion" : 3,
                "inputStage" : {
                    "stage" : "TEXT_MATCH",
                    "inputStage" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                            "stage" : "OR",
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                    "_fts" : "text",
                                    "_ftsx" : 1
                                },
                                "indexName" : "title_content_text",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "backward",
                                "indexBounds" : {
                                    
                                }
                            }
                        }
                    }
                }
            },
            "rejectedPlans" : [ ]
        },
        "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 2,
            "executionTimeMillis" : 6,
            "totalKeysExamined" : 2,
            "totalDocsExamined" : 2,
            "executionStages" : {
                "stage" : "TEXT",
                "nReturned" : 2,
                "executionTimeMillisEstimate" : 0,
                "works" : 3,
                "advanced" : 2,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "indexPrefix" : {
                    
                },
                "indexName" : "title_content_text",
                "parsedTextQuery" : {
                    "terms" : [
                        "kendal"
                    ],
                    "negatedTerms" : [ ],
                    "phrases" : [ ],
                    "negatedPhrases" : [ ]
                },
                "textIndexVersion" : 3,
                "inputStage" : {
                    "stage" : "TEXT_MATCH",
                    "nReturned" : 2,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 3,
                    "advanced" : 2,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 0,
                    "restoreState" : 0,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "docsRejected" : 0,
                    "inputStage" : {
                        "stage" : "FETCH",
                        "nReturned" : 2,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 3,
                        "advanced" : 2,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "docsExamined" : 2,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                            "stage" : "OR",
                            "nReturned" : 2,
                            "executionTimeMillisEstimate" : 0,
                            "works" : 3,
                            "advanced" : 2,
                            "needTime" : 0,
                            "needYield" : 0,
                            "saveState" : 0,
                            "restoreState" : 0,
                            "isEOF" : 1,
                            "invalidates" : 0,
                            "dupsTested" : 2,
                            "dupsDropped" : 0,
                            "recordIdsForgotten" : 0,
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 2,
                                "executionTimeMillisEstimate" : 0,
                                "works" : 3,
                                "advanced" : 2,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 0,
                                "restoreState" : 0,
                                "isEOF" : 1,
                                "invalidates" : 0,
                                "keyPattern" : {
                                    "_fts" : "text",
                                    "_ftsx" : 1
                                },
                                "indexName" : "title_content_text",
                                "isMultiKey" : true,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "backward",
                                "indexBounds" : {
                                    
                                },
                                "keysExamined" : 2,
                                "seeks" : 1,
                                "dupsTested" : 2,
                                "dupsDropped" : 0,
                                "seenInvalidated" : 0
                            }
                        }
                    }
                }
            }
        },
        "serverInfo" : {
            "host" : "--",
            "port" : 27017,
            "version" : "3.6.5",
            "gitVersion" : "a20ecd3e3a174162052ff99913bc2ca9a839d618"
        },
        "ok" : 1
    }

    限制Text扫描的数量

    例如文档:{type:"animal",content:"Animal world"},{type:"fruit",content:"Fruit world"}

    建立复合索引:createIndex({type:1,content:"text"})

    查询:find(type:"animal",$text:{$search:"Animal"})

    这样,只会在type为animal的文档中去搜索关键字,而不会在所有文档中搜索。

    复合text索引不能包括其它特殊索引类型:比如多键索引

    地理空间索引:2dsphere索引(还有一个2d索引,适用于MongoDB2.2以及更早版本,这里不再赘述)

    GeoJSON例子:

    GeoJSON Point:
    <field>: { type: <GeoJSON type> , coordinates: <coordinates> }
    Example:
    location: {
          type: "Point",
          coordinates: [-73.856077, 40.848447]
    }

    添加数据

    db.area.insertMany([{local : { type: "Point", coordinates: [ -73.97, 40.77 ] },name: "Great Barrier Reef",category : "Reef"},{local : { type: "Point", coordinates: [ -60.27, 50.66 ] },name: "The Grand Canyon",category : "Canyon"}])
    Grand Canyon",category : "Canyon"}])
    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("5b7514d7081367733746b097"),
            ObjectId("5b7514d7081367733746b098")
        ]
    }

    创建索引:与2d索引不同,复合2dsphere索引不需要将位置字段作为第一个索引字段

    db.area.createIndex({name:1,local:"2dsphere"})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
    }

    查询

    找到在多边形范围内的所有点和形状
    db.area.find( { local :{ $geoWithin :{ $geometry :{ type : "Polygon" ,coordinates : [ [[ -61 , -61 ] ,[ -61 , 61 ] ,[ 61 , 61 ] ,[ 61 , -61 ],[ -61 , -61 ]] ]} } } } )
    { "_id" : ObjectId("5b7514d7081367733746b098"), "local" : { "type" : "Point", "coordinates" : [ -60.27, 50.66 ] }, "name" : "The Grand Canyon", "category" : "Canyon" }
    查询与指定的GeoJSON对象相交的位置 db
    .area.find( { local :{ $geoIntersects :{ $geometry :{ type : "Polygon" ,coordinates: [ [[ 0 , 0 ] ,[ -73.97 , 40.77 ] ,[ -60 , -31 ] ,[ 0 , 0 ]] ]} } } } ) { "_id" : ObjectId("5b7514d7081367733746b097"), "local" : { "type" : "Point", "coordinates" : [ -73.97, 40.77 ] }, "name" : "Great Barrier Reef", "category" : "Reef" } db.area.find( { local :{ $geoIntersects :{ $geometry :{ type : "Polygon" ,coordinates: [ [[ 0 , 0 ] ,[ -75 , 60 ] ,[ -60 , -31 ] ,[ 0 , 0 ]] ]} } } } ) { "_id" : ObjectId("5b7514d7081367733746b098"), "local" : { "type" : "Point", "coordinates" : [ -60.27, 50.66 ] }, "name" : "The Grand Canyon", "category" : "Canyon" }
    查询离定义点最近的点,并按距离对结果进行排序。GeoJSON数据上的接近查询需要2dsphere索引。 db
    .area.find( { local: { $near : { $geometry: { type: "Point", coordinates: [ <longitude> , <latitude> ] }, $minDistance: <单位是米>, $maxDistance: <单位是米> } } } ) db.area.createIndex({local:"2dsphere"}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } db.area.find({local:{ $near :{$geometry: { type: "Point", coordinates: [ -73.97, 40.77 ] },$minDistance: 10000,$maxDistance: 5000000}}}) { "_id" : ObjectId("5b7514d7081367733746b098"), "local" : { "type" : "Point", "coordinates" : [ -60.27, 50.66 ] }, "name" : "The Grand Canyon", "category" : "Canyon" }

    ..

    以定义的点为中心,查询指定范围内的点【查询指定经纬度,10000英里范围内的文档】
    db.area.find( { local :{ $geoWithin :{ $centerSphere :[ [ -50 , 30 ] , 10000 / 3963.2 ]} } } )
    { "_id" : ObjectId("5b7514d7081367733746b097"), "local" : { "type" : "Point", "coordinates" : [ -73.97, 40.77 ] }, "name" : "Great Barrier Reef", "category" : "Reef" }
    { "_id" : ObjectId("5b7514d7081367733746b098"), "local" : { "type" : "Point", "coordinates" : [ -60.27, 50.66 ] }, "name" : "The Grand Canyon", "category" : "Canyon" }

    地理空间索引:geoHaystack索引

    geoHaystack索引包括一个geoHaystack索引键和一个非地理空间索引键
    geoHaystack索引只支持简单的二进制比较,不支持排序。
    索引必须引用两个字段:location字段和第二个字段。第二个字段用于精确匹配
    要构建haystack索引,在创建索引时必须指定桶大小选项。桶大小为5的索引将定位值分组到指定经度和纬度的5个单位内。桶大小还决定了索引的粒度。

    添加数据

    db.hay_area.insertMany([{pos: { lng : 126.9, lat : 35.2 } , type : "restaurant"},{pos: { lng : 128.0, lat : 36.7 } , type : "national park"}])
    {
        "acknowledged" : true,
        "insertedIds" : [
            ObjectId("5b74ee5eead7a34e0b701091"),
            ObjectId("5b74ee5eead7a34e0b701092")
        ]
    }

    创建索引

    db.hay_area.createIndex({pos:"geoHaystack",type:1},{bucketSize:1})
    {
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "ok" : 1
    }

    要查询haystack索引,请使用geoSearch(类似:geoNear)命令。必须同时指定坐标和要进行地理搜索的附加字段.Haystack索引不适合查询最接近特定位置的完整文档列表

    db.runCommand( { geoSearch : "hay_area" ,search : { type: "restaurant" } ,near : [125.9, 34.6] ,maxDistance : 10 } )
    {
        "results" : [
            {
                "_id" : ObjectId("5b74ee5eead7a34e0b701091"),
                "pos" : {
                    "lng" : 126.9,
                    "lat" : 35.2
                },
                "type" : "restaurant"
            }
        ],
        "stats" : {
            "time" : 1,
            "btreeMatches" : 1,
            "n" : 1
        },
        "ok" : 1
    }

    TTL索引(MongoDB可以使用它在特定的时间之后自动从集合中删除文档)

    使用该索引的字段必须是时间字段,或者包含日期的数组。并且TTL索引是单键索引。
    
    db.demo.createIndex({"updateTime":1},{expireAfterSeconds: 3600})
    
    db.log_events.insert( {
       "createdAt": new Date(),
       "logEvent": 2,
       "logMessage": "Success!"
    } )

    后台完成创建索引的工作

    db.people.createIndex( { zipcode: 1 }, { background: true } )
  • 相关阅读:
    在一组降序排列的数组中插入一个数据,插入后,数组中数据依然按降序排列
    轮播图无限滚动
    微软雅黑的Unicode码和英文名
    javascript中的this
    javascript构造函数及原型对象
    object.prototype.call
    Array.prototype.forEach数组遍历
    键盘event.which属性
    Object.prototype.toString()
    parseInt()解析整数与parsetFloat()解析浮点数
  • 原文地址:https://www.cnblogs.com/LUA123/p/9489695.html
Copyright © 2011-2022 走看看