首页 > 数据库 > MongoDB > 正文

MongoDB通配符索引如何用?

2024-09-07 00:22:36
字体:
来源:转载
供稿:网友
       这篇文章给大家介绍的是关于MongoDB通配符索引的用法内容,小编认为是比较实用,因此分享给大家作参考,有这方面学习需要的朋友可以看看。
 
       MongoDB在4.2 版本推出了Wildcard Indexes,究竟什么是Wildcard Indexes以及Wildcard Indexes适合哪些场景本文结合官方文档以及实际测试进行简单概述。
 
       1、通配符索引示例
 
       因为MongoDB是dynamic schemas,所以应用是可以查询任何已知字段或者随机字段的。假设(此假设案例摘自官方文档),集合colA的UserMetadata字段包含如下数据:
 
{ "userMetadata" : { "likes" : [ "dogs", "cats" ] } }
{ "userMetadata" : { "dislikes" : "pickles" } }
{ "userMetadata" : { "age" : 45 } }
{ "userMetadata" : "inactive" }
       但是在查询的时候可能是如下语句:
 
db.colA.find({ "userMeta2
通配符索引的形式data.likes" : "dogs" })
db.colA.find({ "userMetadata.dislikes" : "pickles" })
db.colA.find({ "userMetadata.age" : { $gt : 30 } })
db.colA.find({ "userMetadata" : "inactive" })
        2、通配符索引的形式
 
       单字段通配符索引
 
{
 "_id" : ObjectId("5ee2df16911d8dfaa91520b4"),
 "product_name" : "Spy Coat",
 "product_attributes" : {
 "material" : [
 "Tweed",
 "Wool",
 "Leather"
 ],
 "size" : {
 "length" : 72,
 "units" : "inches"
 }
 }
}
{
 "_id" : ObjectId("5ee2df30911d8dfaa91520b5"),
 "product_name" : "Spy Pen",
 "product_attributes" : {
 "colors" : [
 "Blue",
 "Black"
 ],
 "secret_feature" : {
 "name" : "laser",
 "power" : "1000",
 "units" : "watts"
 }
 }
}
如果数据结构是上面这样的,其中product_attributes 属性包含任何的结构。
 
        全字段的通配符索引
 
       可以通过下面的语句创建一个索引,索引中包含集合中的所有字段,但是不包括_id(如果想包含_id可以通过wildcardProjection 来设置),如果集合中的字段包含数组或者嵌套对象的话,那么会迭代数组或者嵌套对象并把值放到索引中。
 
Db.product_catalog.createIndex({“$**”:1})  
       给每个文档添加一个address的字段。
 
7777:PRIMARY> db.product_catalog.find().pretty()
{
 "_id" : ObjectId("5ee2df16911d8dfaa91520b4"),
 "product_name" : "Spy Coat",
 "product_attributes" : {
 "material" : [
 "Tweed",
 "Wool",
 "Leather"
 ],
 "size" : {
 "length" : 72,
 "units" : "inches"
 }
 },
 "address" : "Beijing"
}
{
 "_id" : ObjectId("5ee2df30911d8dfaa91520b5"),
 "product_name" : "Spy Pen",
 "product_attributes" : {
 "colors" : [
 "Blue",
 "Black"
 ],
 "secret_feature" : {
 "name" : "laser",
 "power" : "1000",
 "units" : "watts"
 }
 },
 "address" : "Tianjin"
}
 
db.product_catalog.find({"product_name":"Spy Coat","address":"nanji","product_attributes.colors":"Blue"})
 
       在全字段通配符索引的基础上可以明确包含哪些或者不包含哪些字段到通配符索引中,只能是在全字段通配符索引的基础上,单字段的是不可以的:
 
       在全字段的基础上创建一个明确包含哪些字段的索引:
 
db.collection.createIndex(
 { "$**" : 1 },
 { "wildcardProjection" :
 { "fieldA" : 1, "fieldB.fieldC" : 1 }
 }
)
       注意:通配符索引不支持在使用wildcardProjection的时候混合使用包含和排除语句,除了明确指定包含_id字段的时候。
 
       在全字段的基础上创建一个明确不包含哪些字段的索引:
 
db.collection.createIndex(
 { "$**" : 1 },
 { "wildcardProjection" :
 { "fieldA" : 0, "fieldB.fieldC" : 0 }
 }
)
       3、通配符索引的行为
 
       通配符索引的行为根据其字段类型不同而有所不同。
 
字段为对象
如果是对象的话,会将对象中的内容存储到索引中,通配符索引会把对象中的所有嵌套对象加载到索引中。
字段为数组
如果是数组的话,通配符索引遍历数组并且将每个元素都存储到索引中。
如果数组中的元素是一个对象的话,通配符索引把对象中的内容加载到索引中,像上面的加载对象一样。
如果数组中的元素是一个数组的话(就是多维数组),通配符索引并不迭代嵌套数组,相反是把整个嵌套数组作为一个值来看。
其他类型
把值记录到数组中。
通配符索引会持续迭代任何的嵌套对象或者数组直到最底层(就是不能在迭代为止),然后它会索引全路径。
 
       如果超过了8个以上显示数组索引的话MongoDB 会考虑另外的索引或者执行全集合扫描。如下结构:
 
{
 "parentObject" : {
 "nestedArray" : [
 "elementOne",
 {
  "deeplyNestedArray" : [ "elementTwo" ]
 }
 ]
 }
}
       请注意,通配符索引本身对索引文档时遍历文档的深度没有任何限制;该限制仅适用于显式指定精确数组索引的查询。通过发出没有显式数组索引的相同查询,MongoDB可以选择通配符索引来回答查询。
 
       4、通配符索引的限制
 
       1.首先通配符索引是一个稀疏索引,只存放存在的字段在索引里面,不存在的不存放,也就是说当你使用{$exists:false}的时候,是不会走索引的,是全集合扫描。
 
       db.test_new_wildidx.find({"block.attr":{$exists:false}})
 
       db.test_new_wildidx.find({"block.attr":{$exists:true}})  但是支持true的。
 
       2.通配符索引不支持直接等于/不等于一个对象或者数组。
 
       通配符索引会将对象或者数组中的元素加载到索引中,而不是整体放到索引中。故通配符索引不支持直接用文档或者数组来匹配。
 
        3. 通配符索引支持如下索引类型或者或者属性:
 
Compound
TTL
Text
2d (Geospatial)
2dsphere (Geospatial)
Hashed
Unique
 
       4.通配符索引不支持文档中的数组$ne null这种。其实不光是数组,别的字段也同样,只要是$ne都不会使用通配符索引。

(编辑:武林网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表