首页 > 解决方案 > MongoDB 性能:$and 与具有多个键的单个对象

问题描述

我有一个对订单执行一些操作的内部服务,它有一个内置的必需过滤器,服务用户可以通过额外的过滤器。

实现同一目标的两种方法:A)使用$and

async function getOrders ({ optionalFilter = {} }) {
  const baseFilter = { amount: { $gt: 10 } };
  const mergedFilter = { $and: [baseFilter, optionalFilter] };

  return await Order.find(mergedFilter);
}

B)合并所有在同一个对象中

async function getOrders ({ optionalFilter = {} }) {
  const baseFilter = { amount: { $gt: 10 } };
  const mergedFilter = { ...baseFilter, ...optionalFilter };

  return await Order.find(mergedFilter);
}

我更喜欢第一种方法,因为它允许我在不覆盖$gt: 10规则的情况下执行以下操作,而第二种方法会通过覆盖内部规则来破坏代码。

getOrders({ optionalFilter: { amount: { $lt: 50 } } });

我的问题是,选择一个比另一个有什么优势(性能或其他)?

标签: mongodbmongodb-query

解决方案


我的问题是,选择一个比另一个有什么优势(性能或其他)?

  • 简短回答:不。如果您不使用(复合)索引

  • 长答案:好的,让我们测试一下,对吗?

因此,让我们收集约 100k 个文档和未索引的数组字段:

  1. {asset_class: "COMMDTY"} 未编入索引

  2. {$and: [{item_subclass: "Herb", asset_class: "COMMDTY"}]} 和两个未索引的字段

  3. 没有{item_subclass: "Herb", asset_class: "COMMDTY"} 未索引的两个字段

好吧,使用和不使用是有114ms区别的。$and但这是否意味着停止使用$and并避免使用它?当然不是。但是随着字段的增加,Mongo 会变得越慢。但是,当我向查询中添加一个已经索引的字段时,整个情况发生了变化。

{expansion: "BFA", asset_class: "COMMDTY"} 索引两个

因此,如果您通过mergedFilterthen 添加更多字段,请确保您的索引(如果您正在使用它们)可以使用,因为对于复合索引字段顺序非常有意义。所以查询:{asset_class: "COMMDTY", expansion: "BFA" }will 已经进入: 11ms


推荐阅读