在查询匹配后使用mongodb中的聚合来执行更新 [英] Use aggregation in mongodb to perform update after query matches

查看:71
本文介绍了在查询匹配后使用mongodb中的聚合来执行更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用聚合的mongodb查询,查询如下所示

couponmodel.aggregate(
    { $match : { 'brand_id': { $in: brand_ids } } },
    { $project: { _id: 1, arr_size: { $size: "$coupon_codes" }, curr_ctr:1 } },
    function(err, docs) {
        if (err) {

        } else {
            if (docs.length > 0) {
                console.log('docs: ', docs);
            }
        }
    });
};

现在我面临的问题是匹配查询后,我想从我的数组brand_ids中删除(拉出)这个brand_id,因为我想对其余的brand_ids使用匹配查询

任何人都可以告诉我该怎么做.

谢谢.

更新-由于我认为我没有明确提到我要考虑的情况

假设我的brand_ids数组包含以下字符串

brand_ids = ["id1", "id2", "id3", "id4", "id5"] 

和我的数据库有以下文件

{
   "brand_id": "id1",
   "name": "Levis",
   "loc": "india"
},
{
   "brand_id": "id1",
   "name": "Levis"
   "loc": "america"
},
{
   "brand_id": "id2",
   "name": "Lee"
   "loc": "india"
},
{
   "brand_id": "id2",
   "name": "Lee"
   "loc": "america"
}

所需的JSON输出

   {
       "name": "Levis"
    },
    {
       "name": "Lee"
    }

现在对于上面的查询,我只想获得一个"Levis"和一个"Lee"的结果,但是当它们在文档中出现两次时,它们将被返回两次,这就是为什么当第一个"Levis"出现时我要删除它的原因从brand_ids中获取,这样就不会返回下一个"Levis","Lee"也是如此.另外,我这样做是为了减少查询时间,所以不要给我答案,例如带品牌名称和所有名称的小组查询.

希望我的问题现在已经清楚了.

更新-就像所有人都告诉我使用组一样,现在让我告诉你为什么我认为这会增加查询所花费的时间.

对于上面的示例,假设我有25000个文档,其中名称"为"Levis",而25000个文档中名称"为"Lee",现在,如果我使用组,则将查询所有50000个文档并按名称".

但是根据我想要的解决方案,当找到带有"Levis"和"Lee"的第一个文档时,我将不必寻找剩余的数千个文档.

希望您能得到它,实际上我的问题是如何在数组的每个元素上使用findOne,而当我获得任何元素时就不要寻找它.

解决方案

仍不能100%确定您要尝试的内容,但这会创建一个长度为1的结果文档,其中brand_ids的所有匹配项都具有不同的值.

然后,结果将遍历所有品牌并将其从您的brand_ids数组中删除.

couponmodel.aggregate(
    { $match: { "brand_id": { $in: brand_ids } } },
    { $group: { _id: null, brands: { $addToSet: "$brand_id" } } },
    function(err, doc) {
        doc.brands.forEach(function(brand) {
            var idx = array.indexOf(brand);
            if (idx > -1) {
                brand_ids.splice(idx, 1);    
            }
        });
    }
)

I am writing a mongodb query where i am using aggregates, my query is given below

couponmodel.aggregate(
    { $match : { 'brand_id': { $in: brand_ids } } },
    { $project: { _id: 1, arr_size: { $size: "$coupon_codes" }, curr_ctr:1 } },
    function(err, docs) {
        if (err) {

        } else {
            if (docs.length > 0) {
                console.log('docs: ', docs);
            }
        }
    });
};

Now the problem i am facing is after match query i want to delete(pull) this brand_id from my brand_ids which is an array, because i want to use match query for remaining brand_ids

Can anyone please tell me how can do this.

thank you.

UPDATE- As i think i have not clearly mentioned what i am trying to do consider below case

Suppose my brand_ids array contains these strings

brand_ids = ["id1", "id2", "id3", "id4", "id5"] 

and my database have below documents

{
   "brand_id": "id1",
   "name": "Levis",
   "loc": "india"
},
{
   "brand_id": "id1",
   "name": "Levis"
   "loc": "america"
},
{
   "brand_id": "id2",
   "name": "Lee"
   "loc": "india"
},
{
   "brand_id": "id2",
   "name": "Lee"
   "loc": "america"
}

Desired JSON output

   {
       "name": "Levis"
    },
    {
       "name": "Lee"
    }

Now for above query i want to get results with only one "Levis" and one "Lee", but as they appear twice in the document they will be returned twice that's why when first "Levis" appears i want to remove it from brand_ids such that next "Levis" will not get returned and same is the case for "Lee". Also i am doing this to reduce query time so don't give me answer like group query with brand names and all.

Hope my question is clear now.

UPDATE- As everone is telling me to use group now let me tell you why i think it will increase time taken by query.

For above example suppose i have 25000 documents with "name" as "Levis" and 25000 of documents where "name" is "Lee", now if i will use group then all of 50000 documents will be queried and grouped by "name".

But according to the solution i want, when first document with "Levis" and "Lee" gets found then i will don't have to look for remaining thousands of the documents.

Hope you get it, Actually my question is how to use findOne on every element of my array and when i get any element then don't look for it.

解决方案

Still not 100% sure what you're trying but this will create a result document of length 1, with distinct values for all matches of brand_ids.

Then in the result, it will iterate through all of the brands and remove them from your brand_ids array.

couponmodel.aggregate(
    { $match: { "brand_id": { $in: brand_ids } } },
    { $group: { _id: null, brands: { $addToSet: "$brand_id" } } },
    function(err, doc) {
        doc.brands.forEach(function(brand) {
            var idx = array.indexOf(brand);
            if (idx > -1) {
                brand_ids.splice(idx, 1);    
            }
        });
    }
)

这篇关于在查询匹配后使用mongodb中的聚合来执行更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆