草庐IT

MongoDB $project : $filter sub-array

coder 2023-05-05 原文

有一个项目( Mongoose )模式看起来像这样(简化为对问题很重要):

{
    brand: {
        name: String,
    },
    title: String,
    description: [{ lang: String, text: String }],
    shortDescription: [{ lang: String, text: String }],
    variants: {
        cnt: Number,
        attrs: [
            {
                displayType: String,
                displayContent: String,
                displayName: [{ lang: String, text: String }],
                name: String,
            },
        ],
    }
}

我正在尝试按语言过滤项目,因此我构建了以下查询:

db.items.aggregate([
    { $match: { 'description.lang': 'ca', 'shortDescription.lang': 'ca' } },
    { $project: {
        'brand.name': 1,
        title: 1,
        description: {
            '$filter': {
                input: '$description',
                as: 'description',
                cond: { $eq: ['$$description.lang', 'ca'] }
            }
        },
        shortDescription: {
            '$filter': {
                input: '$shortDescription',
                as: 'shortDescription',
                cond: { $eq: ['$$shortDescription.lang', 'ca'] }
            }
        },
        'variants.cnt': 1,
        'variants.attrs': 1
    } }
])

它按预期工作:它按语言过滤 descriptionshortDescription。现在我想知道是否可以过滤每个 variants.attrs.$.displayName 。有什么办法吗?

我一直在尝试 $unwind variant.attrs 但是当我再次尝试 $group 时我完全迷失了,我不确定这是否是最好的方法...

最佳答案

你快到了。请尝试以下步骤:

  • $project 阶段之前使用 $unwind 阶段来扩展文档的外部数组,即 variants.attrs
  • $project 阶段为子数组 variants.attrs.displayName 添加过滤器。
  • 您必须投影 variants 键的所有子字段。
  • 接下来添加 $group 阶段并按除子数组之外的所有元素进行分组。使用$push分阶段重建子数组。
  • 最后,添加 $project 阶段以将文档重建为其原始结构。

    db.items.aggregate([
      { $match: { 'description.lang': 'ca', 'shortDescription.lang': 'ca' } },
      { $unwind : "$variants.attrs" },
      { $project: {
         '_id' : 1,
         'brand.name': 1,
         title: 1,
         description: {
            '$filter': {
                input: '$description',
                as: 'description',
                cond: { $eq: ['$$description.lang', 'ca'] }
            }
         },
         shortDescription: {
           '$filter': {
               input: '$shortDescription',
               as: 'shortDescription',
               cond: { $eq: ['$$shortDescription.lang', 'ca'] }
            }
         },
         'variants.attrs.displayName' : {
            '$filter' : {
               input: '$variants.attrs.displayName',
               as: 'variants_attrs_displayName',
               cond: { $eq : ['$$variants_attrs_displayName.lang','ca']}
            }
          },
    
          'variants.cnt': 1,
          'variants.attrs.displayType': 1,
          'variants.attrs.displayContent' : 1,
          'variants.attrs.name' : 1
        } 
     } , { $group:
              {
                _id : { 
                    _id: "$_id",
                    title: "$title",
                    brand:"$brand",
                    description:"$description",
                    shortDescription:"$shortDescription", 
                    variants_cnt : "$variants.cnt"
                    },
                variants_attrs : { $push : 
                { 
                  displayType : "$variants.attrs.displayType",
                  displayContent : "$variants.attrs.displayContent",
                  displayName : "$variants.attrs.displayName",
                  name: "$variants.attrs.name" 
                }
              }
            }
        },
    { $project : 
     {
        "_id" : 0,
        brand : "$_id.brand",
        title : "$_id.title",
        description : "$_id.description",
        shortDescription : "$_id.shortDescription",
        variants : {
          cnt : "$_id.variants_cnt" ,
          attrs : "$variants_attrs"
         }
       }  
     }
    ])
    

根据您的用例,您应该重新考虑您的 data model design以避免过滤器值的重复。 IE。 'description.lang': 'ca', 'shortDescription.lang': 'ca', 'variants.attrs.displayName.lang': 'ca'

关于MongoDB $project : $filter sub-array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39356612/

有关MongoDB $project : $filter sub-array的更多相关文章

  1. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  2. Ruby Koans about_array_assignment - 非平行与平行分配歧视 - 2

    通过ruby​​koans.com,我在about_array_assignment.rb中遇到了这两段代码你怎么知道第一个是非并行赋值,第二个是一个变量的并行赋值?在我看来,除了命名差异之外,代码几乎完全相同。4deftest_non_parallel_assignment5names=["John","Smith"]6assert_equal["John","Smith"],names7end45deftest_parallel_assignment_with_one_variable46first_name,=["John","Smith"]47assert_equal'John

  3. arrays - 这是 Ruby 中 Array.fill 方法的错误吗? - 2

    这个问题在这里已经有了答案:Arraysmisbehaving(1个回答)关闭6年前。是否应该这样,即我误解了,还是错误?a=Array.new(3,Array.new(3))a[1].fill('g')=>[["g","g","g"],["g","g","g"],["g","g","g"]]它不应该导致:=>[[nil,nil,nil],["g","g","g"],[nil,nil,nil]]

  4. ruby - Arrays Sets 和 SortedSets 在 Ruby 中是如何实现的 - 2

    通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复

  5. Ruby on Rails regexp equals-tilde 与 array include 用于检查选项列表 - 2

    我正在使用Rails3.2.3和Ruby1.9.3p0。我发现我经常需要确定某个字符串是否出现在选项列表中。看来我可以使用Ruby数组.includemethod:或正则表达式equals-tildematchshorthand用竖线分隔选项:就性能而言,一个比另一个好吗?还有更好的方法吗? 最佳答案 总结:Array#include?包含String元素,在接受和拒绝输入时均胜出,对于您的示例只有三个可接受的值。对于要检查的更大的集合,看起来Set#include?和String元素可能会获胜。如何测试我们应该根据经验对此进行测试

  6. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  7. arrays - Ruby:尝试在哈希数组上获取 Enumerator 时,nil:NilClass 的未定义方法 `[]' - 2

    我正在尝试循环哈希数组。当我到达获取枚举器开始循环的位置时,出现以下错误:undefinedmethod`[]'fornil:NilClass我的代码如下所示:defextraireAttributs(attributsParam)classeTrouvee=falsescanTrouve=falseownerOSTrouve=falseownerAppTrouve=falseresultat=Hash.new(0)attributs=Array(attributsParam)attributs.eachdo|attribut|#CRASHESHERE!!!typeAttribut=a

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. ruby - 在 Ruby 中,为什么 Array.new(size, object) 创建一个由对同一对象的多个引用组成的数组? - 2

    如thisanswer中所述,Array.new(size,object)创建一个数组,其中size引用相同的object。hash=Hash.newa=Array.new(2,hash)a[0]['cat']='feline'a#=>[{"cat"=>"feline"},{"cat"=>"feline"}]a[1]['cat']='Felix'a#=>[{"cat"=>"Felix"},{"cat"=>"Felix"}]为什么Ruby会这样做,而不是对object进行dup或clone? 最佳答案 因为那是thedocumenta

  10. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

随机推荐