我有查询:
.find({$where: 'this.lastEmailDate < Date.now() - this.warnTime'})
这是一个非常慢的操作。有没有办法将此查询转换为使用$ lt?
我看到有些人建议创建一个新变量并选择使用它,但问题是Date.now()不断变化。
答案 0 :(得分:1)
由于 $where
运算符具有相当糟糕的性能问题,因此操作速度很慢。原因是当您执行正常(非 $where
)查询时,您的客户端将查询转换为BSON并将其发送到数据库,因为MongoDB将其数据存储为BSON,查询会更快,因为它直接将查询与数据进行比较。
现在使用 $where
运算符查询,MongoDB首先为集合中的每个文档创建一个JavaScript对象,然后解析文档&#39; BSON并将所有字段添加到JS对象。然后它将执行您针对文档发送的JS,然后再将其全部删除 - 这是非常耗费资源的操作,因此使用 $where
子句进行查询速度慢。
现在,最好的方法是利用聚合框架来利用查询。考虑以下管道,它执行完全相同的查询,但速度更快,因此性能更佳:
db.collection.aggregate([
{
"$redact": {
"$cond": [
{
"$eq": [
{ "$comp": [
"$lastEmailDate",
{ "$subtract": [new Date(), "$warnTime"] }
]},
-1
]
},
"$$KEEP",
"$$PRUNE"
]
}
}
])
以上使用 $redact
运算符,它基本上根据文档本身存储的信息限制文档的内容。
根据它所提供的表达式,它会通过使用 $cond
逻辑运算符评估字段来解析查询集合。在 $cond
运算符中,您可以使用 $eq
和 $cmp
和$ subtract运营商确实执行逻辑:
如果 $cmp
操作的结果为-1,则显示返回整个文档(在文档级别),否则)
如果从lastEmailDate
日期
current
小于<asp:GridView ID="gvTable" runat="server" HeaderStyle-Font-Bold="true" AutoGenerateColumns="true"
RowStyle-Font-Bold="true" SelectedRowStyle-Font-Bold="true"
onrowcommand="RowCommand" onrowediting="RowEditing">
<Columns>
<asp:CommandField ShowEditButton="true" ShowDeleteButton="true" ShowInsertButton="true" />
<%-- <asp:BoundField DataField="Date birth" HeaderText="Date birth" DataFormatString="{0:dd.MM.yyyy}" />--%>
</Columns>
</asp:GridView>
, $cmp
表达式将评估为-1 >