1️⃣ 场景

电商商品的 基本信息(名称、分类、价格)是固定的,但 属性参数 是动态的:

  • 手机可能有:屏幕尺寸电池容量CPU

  • 衣服可能有:颜色尺码材质

  • 书籍可能有:作者出版社

👉 这些属性差别太大,不可能像 MySQL 那样提前定义一张字段齐全的表。


2️⃣ 数据模型

{ "_id": ObjectId("..."), "name": "iPhone 15", "category": "手机", "price": 6999, "attributes": { "屏幕尺寸": "6.1英寸", "电池容量": "3200mAh", "CPU": "A17" } }
{ "_id": ObjectId("..."), "name": "Nike T-Shirt", "category": "衣服", "price": 299, "attributes": { "颜色": "黑色", "尺码": "XL", "材质": "棉" } }

3️⃣ 通配符索引的使用

方式一:给所有属性字段建索引

db.products.createIndex({ "attributes.$**": 1 })

👉 查询时,MongoDB 会为 attributes 下的每个键(如 "颜色", "尺码", "CPU")建索引。


方式二:查询示例

  1. 查询某个属性:

db.products.find({ "attributes.颜色": "黑色" })

✅ 能走索引。

  1. 查询手机 CPU:

db.products.find({ "attributes.CPU": "A17" })

✅ 能走索引。

  1. 查询衣服的尺码:

db.products.find({ "attributes.尺码": "XL" })

✅ 也能走索引。

👉 不用提前知道有哪些属性,任何属性都能查。


方式三:通配符复合索引(过滤 + 属性查询)

如果你经常需要 先过滤分类,再查属性

db.products.createIndex({ category: 1, "attributes.$**": 1 })

查询:

db.products.find({ category: "衣服", "attributes.尺码": "XL" })

👉 索引先用 category,再用 attributes 下的动态字段。


方式四:通配符投影(限制索引字段范围)

如果属性太多,只想索引部分(比如只索引 颜色尺码):

db.products.createIndex( { "attributes.$**": 1 }, { wildcardProjection: { "attributes.颜色": 1, "attributes.尺码": 1 } } )

👉 节省存储空间,提高效率。


4️⃣ 对比 MySQL

  • MongoDB

    • attributes 用文档存储,动态扩展属性非常方便。

    • 通配符索引解决了“字段不固定,查询又要走索引”的问题。

  • MySQL

    • 要么设计一张 商品属性表product_id, attr_name, attr_value),然后 join;

    • 要么用 JSON 存,但 JSON 查询和索引性能较差。


✅ 总结

  • 电商商品属性是通配符索引的经典应用场景。

  • 通配符索引让 动态属性 可以被高效查询,不需要预先建索引。

  • 如果只关心少量属性,可以用 通配符投影,节省存储和写入开销。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部