【问题标题】:How do I identify that an array has unique entries in MongoDB?如何识别数组在 MongoDB 中具有唯一条目?
【发布时间】:2016-10-17 07:43:47
【问题描述】:

我有一个字符串数组

users: ['user1', 'user2']

如果我运行搜索以按该顺序准确查找 ['user1', 'user2'],它将找到该条目。但是,如果它们从后到前,则查询不会返回任何内容。

将输入数组与数据库中的列表进行比较以确定它是否是唯一条目的最佳方法是什么?

【问题讨论】:

标签: javascript arrays mongodb


【解决方案1】:

您可以通过以下查询识别集合中的唯一数组。

db.getCollection('mycollection').find({users:  { $size: 2, $all: [ "user1" , "user2" ]  }})

您需要提及编号。您正在检查的数组中的元素,并通过 $all 运算符检查其中的所有元素。

【讨论】:

    【解决方案2】:

    将聚合框架与 $redact 管道运算符一起使用,您可以使用 $cond 运算符处理逻辑条件并使用特殊操作 @ 987654323@“保留”逻辑条件为真的文档或$$PRUNE“删除”条件为假的文档。

    此操作类似于具有 $project 管道,它选择集合中的字段并创建一个新字段来保存逻辑条件查询的结果,然后是后续 @ 987654326@,除了 $redact 使用更高效的单个流水线阶段。

    至于逻辑条件,您可以使用Set Operators,因为它们允许对数组执行集合操作的表达式,将数组视为集合。设置表达式忽略每个输入数组中的重复条目和元素的顺序,这在您的情况下是一个合适的属性,因为您 想要忽略元素的顺序。

    您可以使用其中几个运算符来执行逻辑条件,即 $setIsSubset$setDifference


    考虑以下证明上述概念的示例:

    填充测试集合

    db.collection.insert([
        { users: ['user1', 'user2'] },
        { users: ['user1', 'user2', 'user2'] },
        { users: ['user1', 'user2', 'user3'] },
        { users: ['user1', 'user3'] },
    ])
    

    示例 1: $redact$setEquals

    var arr = [ "user2", "user1" ];
    db.collection.aggregate([
        { 
            "$redact": {
                "$cond": [
                    { "$setEquals": [ "$users", arr ] },
                    "$$KEEP",
                    "$$PRUNE"
                ]
            }
        }
    ])
    

    样本输出

    /* 1 */
    {
        "_id" : ObjectId("5804902900ce8cbd028523d1"),
        "users" : [ 
            "user1", 
            "user2"
        ]
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5804902900ce8cbd028523d2"),
        "users" : [ 
            "user1", 
            "user2", 
            "user2"
        ]
    }
    

    示例 2: $redact$setDifference

    var arr = [ "user2", "user1" ];
    db.collection.aggregate([
        { 
            "$redact": {
                "$cond": [
                    { 
                        "$eq": [
                            { "$setDifference": [ "$users", arr ] },
                            []
                        ]
                    },
                    "$$KEEP",
                    "$$PRUNE"
                ]
            }
        }
    ])
    

    样本输出

    /* 1 */
    {
        "_id" : ObjectId("5804902900ce8cbd028523d1"),
        "users" : [ 
            "user1", 
            "user2"
        ]
    }
    
    /* 2 */
    {
        "_id" : ObjectId("5804902900ce8cbd028523d2"),
        "users" : [ 
            "user1", 
            "user2", 
            "user2"
        ]
    }
    

    另一种方法,虽然只在 $redact 不可用时推荐,但将 $where 运算符用作:

    db.collection.find({
        "$where": function() {
            var arr = ["user2", "user1"];
            return !(this.users.sort() > arr.sort() || this.users.sort() < arr.sort());
        }
    })
    

    但是,请记住,这不会很好,因为使用 $where 运算符的查询操作会调用 JavaScript 引擎来评估每个文档上的 JavaScript 代码并检查每个文档的条件.

    这非常慢,因为 MongoDB 在 $where 表达式和非$where 查询之前评估非$where 查询操作语句可以使用索引。

    如果可以的话,建议结合索引查询,这样查询可能会更快。但是,当您无法以任何其他方式构造数据或处理一小部分数据时,建议您使用 JavaScript 表达式和 $where 运算符作为最后的手段。

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 2021-05-22
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 2011-01-24
      • 2020-03-23
      相关资源
      最近更新 更多