如何识别数组在MongoDB中具有唯一条目?

时间:2016-10-17 07:43:48

标签: javascript arrays mongodb

我有一个字符串数组

users: ['user1', 'user2']

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

使用聚合框架和 $redact 管道运算符,您可以使用 $cond 运算符处理逻辑条件并使用特殊操作 $$KEEP 至"保持"逻辑条件为真的文档或 $$PRUNE 到"删除"条件错误的文件。

此操作类似于具有 $project 管道,该管道选择集合中的字段并创建一个新字段,其中包含逻辑条件查询的结果,然后是后续的 $match ,但 $redact 使用效率更高的单个管道阶段。

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

您可以使用其中几个运算符来执行逻辑条件,即 $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 表达式和非 {{3}之前评估非 $where 查询操作,因此速度非常慢} 查询语句可能使用索引。

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