Mongodb更新重复数组值

Mongodb更新重复数组值,mongodb,mongodb-query,Mongodb,Mongodb Query,我正在获取一个数据数组,然后想将其插入我的mongodb。我想用新的值覆盖任何重复的值(在Im上传时),如果没有重复的值,只需将其添加到当前数组中 我目前有: db.cases.updateOne( { companyID: 218 }, { $addToSet: { cases: [AN ARRAY OF CASES] }, $currentDate: { lastModified: true } }) 该系列有多家

我正在获取一个数据数组,然后想将其插入我的mongodb。我想用新的值覆盖任何重复的值(在Im上传时),如果没有重复的值,只需将其添加到当前数组中

我目前有:

db.cases.updateOne(
    { companyID: 218 },
    {
      $addToSet: {
        cases: [AN ARRAY OF CASES]
      },
      $currentDate: { lastModified: true }
    })
该系列有多家公司,每家公司都有一系列案例-见下图:

另一件似乎不起作用的事情是,每当我更新案例时,currentDate似乎不会改变,不确定这是否是我编写查询的方式

谢谢。

您可以将$addToSet()与$[]一起使用来完成此操作

我在Node.js中编写了一个示例,向您展示我的意思:

const { MongoClient } = require('mongodb');

async function main() {
    /**
     * Connection URI. Update <username>, <password>, and <your-cluster-url> to reflect your cluster.
     */
    const uri = "mongodb+srv://<username>:<password>@<your-cluster-url>?retryWrites=true&w=majority";

    /**
     * The Mongo Client you will use to interact with your database
     */
    const client = new MongoClient(uri, { useUnifiedTopology: true });

    try {
        // Connect to the MongoDB cluster
        await client.connect();

        // Make the appropriate DB calls
        await updateArray(client, 'id1')


    } finally {
        // Close the connection to the MongoDB cluster
        await client.close();
    }
}

main().catch(console.error);

async function updateArray(client, id) {
    const docId = "299";
    const mynewdoc = {
        id: docId,
        priority: 5,
        casenumber: 40,
        new: "field"
    }
    const result = await client.db("NameOfYourDb").collection("NameOfYourCollection").updateOne(
        { _id: id },
        {
            $set: {
                "cases.$[element]": mynewdoc
            }
        },
        {
            arrayFilters: [{ "element.id": docId }]
        }
    )

    if (result) {
        console.log(result);
    } else {
        console.log(`Not found '${id}'`);
    }

    const result2 = await client.db("NameOfYourDb").collection("NameOfYourCollection").updateOne(
        { _id: id },
        {
            $addToSet: {
                "cases": mynewdoc
            }
        }
    )

    if (result2) {
        console.log(result2);
    } else {
        console.log(`Not found '${id}'`);
    }

}

const{MongoClient}=require('mongodb');
异步函数main(){
/**
*更新,以反映您的集群。
*/
const uri=“mongodb+srv://:@?retryWrites=true&w=mailty”;
/**
*用于与数据库交互的Mongo客户端
*/
const client=new MongoClient(uri,{useUnifiedTopology:true});
试一试{
//连接到MongoDB集群
等待client.connect();
//进行适当的数据库调用
等待UpdateRay(客户端“id1”)
}最后{
//关闭与MongoDB群集的连接
等待客户端。关闭();
}
}
main().catch(console.error);
异步函数updateArray(客户端,id){
const docId=“299”;
常量mynewdoc={
id:docId,
优先事项:5,
案件编号:40,
新:“场”
}
const result=await client.db(“NameOfYourDb”).collection(“NameOfYourCollection”).updateOne(
{{u id:id},
{
$set:{
“案例$[element]”:mynewdoc
}
},
{
数组过滤器:[{“element.id”:docId}]
}
)
如果(结果){
控制台日志(结果);
}否则{
log(`notfound'${id}``);
}
const result2=await client.db(“NameOfYourDb”).collection(“NameOfYourCollection”).updateOne(
{{u id:id},
{
$addToSet:{
“案例”:mynewdoc
}
}
)
如果(结果2){
console.log(result2);
}否则{
log(`notfound'${id}``);
}
}

有关Node.js代码的结构说明,请参阅。

因此我找到了一个解决方法,但这并不完全是我想要的-也许有人可以使用它并对其进行扩展以使其更好地工作:

db.cases.aggregate(
    { $match: { 'companyID': 218 }},
    { $unwind: '$cases' }, 
    { $group: { "_id": "$cases.casenumber", cases: {$push:'$cases'}, "count": { $sum:1 }}},
    { $match: { "count": { "$gt": 1 }}}
    { $project: { "cases": { $slice: [ "$cases", -1, { $subtract: [ { $size: "$cases" }, 1 ]}] }}},
    { $project: { "cases": { $arrayElemAt: ['$cases', 0] }}},
    { $group: { _id: 1, cases: {$push:'$cases' }}},
    { $out: 'cases' }
)
唯一的问题是使用out会覆盖cases文档,因此我需要找到一种方法将其写入公司id(218)中的cases数组

希望这能帮助一些人


谢谢。

使用
$addToSet
@MarkMeyer添加数组。唯一的问题是,如果存在重复项,$addToSet对数组没有任何作用,但我希望在值发生更改时将该重复项更新为最新值。如果值发生更改,则不再是重复项。重复的对象需要精确匹配。“…您不能指定MongoDB仅比较文档中字段的子集,以确定文档是否是现有数组元素的副本。”@MarkMeyer感谢这一点。因此,没有一种方法可以循环查看我要添加的案例是否包含id为299的案例,如果是,我必须覆盖该案例?不这样做的问题是,我现在有两个id为299的案例版本,这使得我计算的统计数据不正确。听起来你最好使用
update
(或类似)并设置为true。这将更新现有文档,或者在它们不存在的情况下创建它们。我想到了一个新的解决方案,但想知道它是否可能——我是否可以将所有文档都添加到数组中,然后在数组中循环查找所有具有相同案例编号的文档,然后删除第一个(最早的)案例?我有代码要添加到数组中,它只是查找重复的案例号并删除最旧的。听起来好像可以。性能方面-可能需要一段时间来迭代数组中的每个元素,以便在以后的数组中查找重复的元素。我添加了一个答案,但并不完全符合我的需要-您对如何将其保存到特定文档中有何想法?我想您需要做的是确保每个阶段都保留前一阶段。然后,您需要在最后按companyId对它们进行分组,以获取原始文档。