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

mongodb 创建局部索引【Partial Indexes】

程序员文章站 2024-03-17 20:38:40
...

环境

mongodb:3.4
工具:Robo 3T1.1

前言

还是前几天的问题: mongodb中$nin操作的优化

今天在调相关接口时,第一次还是慢的出不来,之前我说把$nin换成$gt,但是效果依旧不理想。

今天看官网文档时,发现了好东西Partial Indexes
这个是,mongodb3.2增加的特性。

实战

先说下我的业务情况。

mongodb 创建局部索引【Partial Indexes】

我这个接口需要拿的数据如上图;

由于摘要字段 的字符很长,所以无法对该字段创建有效的索引(ir_urlcontent:1不能创建);
我的查询语句:

db.urlcontents.count({ir_groupname:"产业热点", ir_urlcontent:{$gt:""}})

说明:

假设没有创建局部索引(Partial Indexes)的话,并且数据库总量是72万,查询时间大概需要10s以上。
说明下,已经创建了ir_groupname_1_ir_urltime_-1_ir_urltitle_1这样的索引,ir_urlcontent因为字符太长,无法创建索引(ir_urlcontent: 1)。

创建局部索引

db.urlcontents.createIndex({ir_groupname:1, ir_urltime:-1},
                           {partialFilterExpression:{ir_urlcontent:{$gt:""}}},
                           {background:1})

之后再执行,时间变成了4s左右。

mongodb 创建局部索引【Partial Indexes】

可以看出,效果相比之前10s是好多啦!
但是4s,其实依旧很慢啦!

目前我就优化到这!

局部索引的语法

Partial Index 并不是每个命令都支持的!

支持的表达式:

$eq
$gt,$gte,$lt,$lte
$type
$and 只用于*操作

也就是partialFilterExpression中所支持的表达式;

创建的语句类似于上面的:

db.urlcontents.createIndex({ir_groupname:1, ir_urltime:-1},
                           {partialFilterExpression:{ir_urlcontent:{$gt:""}}},
                           {background:1})

这样的形式;

其实很简单,不多讲了

限制

拿上面的例子来说,假设现在我又想创建一个这样的索引:

db.urlcontents.createIndex({ir_groupname:1, ir_urltime:-1},
                           {partialFilterExpression:{ir_urltime:{$gt:""}}},
                           {background:1})

和上面的区别在于partialFilterExpression表达式中的ir_urlcontent字段换成了ir_urltime字段。

执行后会提示错误:

{
    "raw" : {
        "shard1/10.6.11.122:27018" : {
            "ok" : 0.0,
            "errmsg" : "Index with name: ir_groupname_1_ir_urltime_-1 already exists with different options",
            "code" : 85,
            "codeName" : "IndexOptionsConflict",
            "$gleStats" : {
                "lastOpTime" : {
                    "ts" : Timestamp(1517820607, 650),
                    "t" : NumberLong(4)
                },
                "electionId" : ObjectId("7fffffff0000000000000004")
            }
        }
    },
    "code" : 85,
    "ok" : 0.0,
    "errmsg" : "{ shard1/10.6.11.122:27018: \"Index with name: ir_groupname_1_ir_urltime_-1 already exists with different options\" }"
}

提示上也说了,该索引已经存在了!

换句话说:不能创建,仅因为过滤器表达式不同的索引

其实从索引名称就可以看出:
我们看下之前我们创建的局部索引:

    {
        "v" : 2,
        "key" : {
            "ir_groupname" : 1.0,
            "ir_urltime" : -1.0
        },
        "name" : "ir_groupname_1_ir_urltime_-1",
        "ns" : "gg_stock_db.urlcontents",
        "partialFilterExpression" : {
            "ir_urlcontent" : {
                "$gt" : ""
            }
        }
    }

看到name部分,其值为ir_groupname_1_ir_urltime_-1;也就是说,mongodb是根据keysort来创建索引名称。

key又是什么东西呢?我们看看createIndex的语法:

字段 类型
keys document
options document

document我们的实际写法就是json字符串。

db.urlcontents.createIndex({ir_groupname:1, ir_urltime:-1}, <注意>---keys </注意>
                           {partialFilterExpression:{ir_urltime:{$gt:""}}},<注意>---options</注意>
                           {background:1}) <注意>--- options</注意>

也就是说,不管创建什么索引,keys部分都不能相同,否则就当做重复索引,不让创建。

和Unique结合做唯一限制

这里我就翻译下官方文档:

假设我们现在有这样一个集合数据:

{ "_id" : ObjectId("56424f1efa0358a27fa1f99a"), "username" : "david", "age" : 29 }
{ "_id" : ObjectId("56424f37fa0358a27fa1f99b"), "username" : "amanda", "age" : 35 }
{ "_id" : ObjectId("56424fe2fa0358a27fa1f99c"), "username" : "rajiv", "age" : 57 }

现在我们创建一个uniquepartialFilterExpression结合使用的索引:

db.users.createIndex(
   { username: 1 },
   { unique: true, partialFilterExpression: { age: { $gte: 21 } } }
)

假设我们要执行如下命令时,都会失败:

db.users.insert( { username: "david", age: 27 } )
db.users.insert( { username: "amanda", age: 25 } )
db.users.insert( { username: "rajiv", age: 32 } )

因为被我们刚刚创建的那个索引给限制了!
具体分析就是:

username:”david”,数据库中已经有一条age:29的记录,所以再插入age:27时,被局部唯一性索引所限制,所以

但是如果我们执行如下操作的话,则会成功:

db.users.insert( { username: "david", age: 20 } )
db.users.insert( { username: "amanda" } )
db.users.insert( { username: "rajiv", age: null } )

参考地址:

https://docs.mongodb.com/manual/core/index-partial/

相关标签: mongodb Index