代码之家  ›  专栏  ›  技术社区  ›  memo

具有不同键名和数组对象的复杂mongodb查询

  •  0
  • memo  · 技术社区  · 4 年前

    我的问题有两部分。我的文档结构如下。

    1. 我基本上想查询数组中的项目 foo.*.bar.* .我怎么才能访问 bar 在查询中,如果 foo (即父母 酒吧 )每份文件都不一样吗?

    2. 特别地, 酒吧 是一个可变长度数组。这些项目 酒吧 可以保持来自固定集合(例如。 cat , dog , cow 等等)。还有 酒吧 可能有任何数量的这些,以任何顺序。我想问一下: 那些有 只有一个 酒吧 其包含一个或多个特定项目 例如。 =>它将返回文档#2。(尽管它有两个 cats 在一个 酒吧 ,它只有一个 酒吧 具有 .

    为了更清楚地说明这一点,这里是谓词的伪代码:I

    predictate(document, item):
        bars_which_contain_item = 0
        foreach currentFoo in document.foo:
           if currentFoo.bar.contains(item) bars_which_contain_item += 1
        return bars-which-contain-item == 1;
     
    

    我查看了有关查询的文档 arrays , embedded documents arrays of embedded documents ,但我找不到答案。我想做的事情有可能吗?或者,我是否需要添加一个遍历所有数据的pass,并添加numberOfCats、numberofDogs和numberOfCows字段,以允许将来进行此类查询?(我不需要经常进行这种查询,性能也不太重要)。

    附言:我使用的是nodejs,但我想查询结构不会改变太多。(此外,如果我能在MongoDB Compass中执行查询,那就更好了)。

    {
       _id: 1,
       foo: {
          a : { bar: ['cat', 'dog', 'cow'] },
          b : { bar: ['cat', 'cat', 'dog'] },
       }
    },
    {
       _id: 2,
       foo: {
          c : { bar: ['cow'] },
          d : { bar: ['dog'] },
          e : { bar: ['cow'] },
          f : { bar: ['cat', 'dog', 'cat'] },
       }
    },
    {
       _id: 3,
       foo: {
          g : { bar: ['cat', 'cow'] },
          h : { bar: ['cow'] },
          i : { bar: ['cat'] },
       }
    }
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   D. SM    4 年前

    对于第一个问题,使用 https://docs.mongodb.com/manual/reference/operator/aggregation/objectToArray/ .

    r = db.foo.aggregate([
      {$project: {foo: {$objectToArray: '$foo'}}},
      {$project: {foo: '$foo.v'}},
    ])
    
    # =>
    
    {"_id":1,"foo":[{"bar":["cat","dog","cow"]},{"bar":["cat","cat","dog"]}]}
    {"_id":2,"foo":[{"bar":["cow"]},{"bar":["dog"]},{"bar":["cow"]},{"bar":["cat","dog","cat"]}]}
    {"_id":3,"foo":[{"bar":["cat","cow"]},{"bar":["cow"]},{"bar":["cat"]}]}
    
    

    关于你的第二个问题:

    
    r = db.foo.aggregate([
      {$project: {foo: {$objectToArray: '$foo'}}},
      {$project: {foo: '$foo.v'}},
      {$project: {foo: {$cond: {
        if: {eq: ['cat', '$foo.bar']},
        then: '$foo.bar',
        else: '$$REMOVE',
      }}}},
      {$project: {foo: {$filter: {
        input: '$foo',
        as: 'x',
        cond: {$in: ['cat', '$$x']},
      }}}},
      {$match: {foo: {$size: 1}}},
    ])
    
    
    {"_id":2,"foo":[["cat","dog","cat"]]}
    
    
    推荐文章