如何返回两个字段具有相同值的文档

use*_*695 6 mongodb meteor mongodb-query aggregation-framework

是否有可能只在两个给定字段中找到具有相同值的集合中的那些文档?

{
    _id:    'fewSFDewvfG20df', 
    start:  10,
    end:    10
}
Run Code Online (Sandbox Code Playgroud)

由于这里startend具有相同的值,该文件会被选中.

我想像......

Collection.find({ start: { $eq: end } })
Run Code Online (Sandbox Code Playgroud)

......这不会起作用,因为end它必须是一种价值.

Ash*_*shh 8

您可以$expr在 mongodb 3.6 中使用来匹配同一文档中的两个字段。

db.collection.find({ "$expr": { "$eq": ["$start", "$end"] } })
Run Code Online (Sandbox Code Playgroud)

或聚合

db.collection.aggregate([
  { "$match": { "$expr": { "$eq": ["$start", "$end"] }}}
])
Run Code Online (Sandbox Code Playgroud)


sty*_*ane 6

你有两个选择.第一个是使用$where运算符.

Collection.find( { $where: "this.start === this.end" } )
Run Code Online (Sandbox Code Playgroud)

第二种选择是使用聚合框架和$redact运算符.

Collection.aggregate([
    { "$redact": { 
        "$cond": [
            { "$eq": [ "$start", "$end" ] },
            "$$KEEP",
            "$$PRUNE"
        ]
    }}
])
Run Code Online (Sandbox Code Playgroud)

哪一个更好?

$where运营商做了一个JavaScript评估和使用不能利用索引,以便查询$where可能会导致的性能在应用程序的下降.见注意事项.如果你使用$,你的每个文件将在$ where操作之前从BSON转换为JavaScript对象,这将导致性能下降.当然,如果您有索引过滤器,则可以改进查询.如果您根据用户输入动态构建查询,则存在安全风险.

$redact$where不使用索引,甚至执行一个集合扫描,但你的查询性能提高了你的时候$redact,因为它是一个标准的MongoDB运营商.这就是说聚合选项要好得多,因为你总是可以使用$ match运算符过滤你的文档.

$where这里很好,但可以避免.此外,我相信只有$where在遇到架构设计问题时才需要.例如,在索引文档中添加另一个布尔字段可能是一个不错的选择.