使用文档字段选择Mongodb查询

时间:2016-06-08 15:14:48

标签: mongodb

我有查询:

.find({$where: 'this.lastEmailDate < Date.now() - this.warnTime'})

这是一个非常慢的操作。有没有办法将此查询转换为使用$ lt?

我看到有些人建议创建一个新变量并选择使用它,但问题是Date.now()不断变化。

1 个答案:

答案 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日期warnTime后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 >