Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在Mongo DB中的数组中查找重复值,但它可以出现在对象外部_Javascript_Arrays_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Javascript 在Mongo DB中的数组中查找重复值,但它可以出现在对象外部

Javascript 在Mongo DB中的数组中查找重复值,但它可以出现在对象外部,javascript,arrays,mongodb,mongodb-query,aggregation-framework,Javascript,Arrays,Mongodb,Mongodb Query,Aggregation Framework,我想要一个查询,它将给我的用户名,其中serialNumber值是重复的。一个库中的序列号值可以存在于其他用户名库中,但不应存在于某个特定用户名库中尝试以下查询: { "_id" : ObjectId("15672"), "userName" : "4567", "library" : [ { "serialNumber" : "Book_1" }, { "serialNu

我想要一个查询,它将给我的用户名,其中serialNumber值是重复的。一个库中的序列号值可以存在于其他用户名库中,但不应存在于某个特定用户名库中

尝试以下查询:

{
    "_id" : ObjectId("15672"),
    "userName" : "4567",
    "library" : [ 
        {
            "serialNumber" : "Book_1"
        }, 
        {
            "serialNumber" : "Book_2"
        }, 
        {
            "serialNumber" : "Book_4"
        }
    ]
},
{
    "_id" : ObjectId("123456"),
    "userName" : "123",
    "library" : [ 
        {
            "serialNumber" : "Book_2"
        }
    ]
},
{
    "_id" : ObjectId("1835242"),
    "userName" : "13526",
    "library" : [ 
        {
            "serialNumber" : "Book_7"
        }, 
        {
            "serialNumber" : "Book_6"
        }, 
        {
            "serialNumber" : "Book_5"
        }, 
        {
            "serialNumber" : "Book_4"
        }, 
        {
            "serialNumber" : "Book_3"
        }, 
        {
            "serialNumber" : "Book_5"
        }
    ]
}
另一种方法是通过
$unwind
来实现这一点,但这在大型数据集上并不可取,因为它会爆炸您的收藏

测试:

或者从该链接中@Dennis的答案中,您可以尝试以下操作:

db.collection.aggregate([
    /** First match stage is optional if all of your docs are of type array & not empty */
    { $match: { $expr: { $and: [{ $eq: [{ $type: "$library" }, "array"] }, { $ne: ["$library", []] }] } } },
    /** Add a new field allUnique to each doc, will be false where if elements in library have duplicates */
    {
        $addFields: {
            allUnique: {
                $eq: [
                    {
                        $size:
                        {
                            $reduce: {
                                input: "$library.serialNumber",
                                initialValue: [], // start with empty array
                                /** iterate over serialNumber's array from library & push current value if it's not there in array, at the end reduce would produce an array with uniques */
                                in: { $cond: [{ $in: ["$$this", "$$value"] }, [], { $concatArrays: [["$$this"], "$$value"] }] }
                            }
                        }
                    },
                    {
                        $size: "$library"
                    }
                ]
            }
        }
    },
    /** get docs where allUnique: false */
    {
        $match: {
            allUnique: false
        }
    },
    /** Project only needed fields & remove _id which is bydefault projected */
    {
        $project: {
            userName: 1,
            _id: 0
        }
    }
])

测试:

您可以在
数组字段上使用聚合运算符,这将返回唯一元素的数组(称之为
库_unique
)。然后,比较
library
library\u unique
的大小(
$size
聚合运算符给出数组的长度)。如果大小不相等,这意味着该文档的
数组中存在重复元素。非常感谢您,whoami,但我忘记了一点,如果库数组中没有serialNumber键,那么它仍然会给我该用户名,我不想要该用户名,您可以在查询中更新该条件吗,这将非常有帮助me@AbhishekKV:请尝试以下操作::,而不是
{$ne:[“$library”,[]}
添加
{$eq:[{$type:“$library.serialNumber”},“array”]}
@AbhishekKV:也许不必进行类型检查,只需检查“library.serialNumber”不是空数组即可
db.collection.aggregate([
  {
    $match: {
      $expr: {
        $and: [
          {
            $eq: [
              {
                $type: "$library"
              },
              "array"
            ]
          },
          {
            $ne: [
              "$library",
              []
            ]
          }
        ]
      }
    }
  },
  {
    $addFields: {
      allUnique: {
        $eq: [
          {
            $size: {
              "$setUnion": [
                "$library.serialNumber",
                []
              ]
            }
          },
          {
            $size: "$library"
          }
        ]
      }
    }
  },
  {
    $match: {
      allUnique: false
    }
  },
  {
    $project: {
      userName: 1,
      _id: 0
    }
  }
])