Py学习  »  MongoDB

如何在Mongodb中将每个数组字段匹配到其他字段

DD DD • 5 年前 • 783 次点击  

const test = [{
    "_id": 1,
    "name": "apple",
    "car": "ford"
},{
    "_id": 2,
    "name": "melon",
    "car": "ferrari"
},{
    "_id": 3,
    "name": "perl",
    "car": "Renaut"
}]

Mongodb的文档如下:

[{
  "name": "perl", "company": "A"
},{
  "name": "melon", "company": "B"
},{
  "name": "apple", "company": "C"
},{
  "name": "apple", "company": "D"
},{
  "name": "perl", "company": "E"
},{
  "name": "apple", "company": "F"
}]

我想用mongodb聚合得到这个结果:

[{
  "name": "perl", "company": "A", testInform: { "_id": 3, "name": "perl", "car": "Renaut"}
},{
  "name": "melon", "company": "B", testInform: { "_id": 2, "name": "melon", "car": "ferrari"}
},{
  "name": "apple", "company": "C", testInform: { "_id": 1, "name": "apple", "car": "ford"}
},{
  "name": "apple", "company": "D", testInform: { "_id": 1, "name": "apple", "car": "ford"}
},{
  "name": "perl", "company": "E", testInform: { "_id": 3, "name": "perl", "car": "Renaut"}
},{
  "name": "apple", "company": "F", testInform: { "_id": 1, "name": "apple", "car": "ford"}
}]

我想用聚合 $match $facet 等等,但我不知道该怎么做。你能推荐一个解决方案吗?

非常感谢您阅读本文。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/54316
 
783 次点击  
文章 [ 3 ]  |  最新文章 5 年前
prasad_
Reply   •   1 楼
prasad_    5 年前

test 数组并将数组元素作为与 name $reduce 操作员)。

const test = [ { ... }, ... ]

db.test_coll.aggregate( [
  { 
      $addFields: { 
          testInform: { 
              $reduce: {
                  input: test,
                  initialValue: { },
                  in: {
                      $cond: [ { $eq: [ "$$this.name", "$name" ] }, 
                               { $mergeObjects: [ "$$this", "$$value" ] }, 
                               "$$value"
                             ]
                      }
               }
          }
      }
  }
] )
ambianBeing
Reply   •   2 楼
ambianBeing    5 年前

如果 test 数组数据存储在一个集合中,那么实现O/P非常简单 $lookup 具有 $project 聚合

$arrayElemAt 为什么?因为查找将作为 testInform

db.maindocs.aggregate([
  {
    $lookup: {
      from: "testdocs",
      localField: "name",
      foreignField: "name",
      as: "testInform"
    }
  },
  {
    $project: {
      _id: 0,
      name: 1,
      company: 1,
      testInform: { $arrayElemAt: ["$testInform", 0] }
    }
  }
]);

其思想是迭代 cursor Array.prototype.find() 对象来自 符合 name 字段,将其添加到结果中。

const test = [
  {
    _id: 1,
    name: "apple",
    car: "ford"
  },
  {
    _id: 2,
    name: "melon",
    car: "ferrari"
  },
  {
    _id: 3,
    name: "perl",
    car: "Renaut"
  }
];


const cursor = db.collection("maindocs").find();
const result = [];

while (await cursor.hasNext()) {
  const doc = await cursor.next();
  const found = test.find(e => e.name === doc.name);
  if (found) {
    doc["testInform"] = found;
  }
  result.push(doc);
}

console.info("RESULT::", result);
Mahesh Bhatnagar
Reply   •   3 楼
Mahesh Bhatnagar    5 年前

$查找

db.demo2.aggregate(
    {
      $lookup:
         {
           from: "demo1",
           let: { recordName: "$name"},
           pipeline: [
              { $match:
                 { $expr:
                    { $and:
                       [
                         { $eq: [ "$$recordName",  "$name" ] },
                       ]
                    }
                 }
              },
           ],
           as: "testInform"
         }

    }
    )