sourcecode

같은 스테이트먼트에서 입력과 집약을 어떻게 사용하는가?

copyscript 2023. 3. 5. 10:16
반응형

같은 스테이트먼트에서 입력과 집약을 어떻게 사용하는가?

다음은 제 예약 모음입니다.

{ _id: ObjectId("518ee0bc9be1909012000002"), date: ISODate("2013-05-13T22:00:00Z"), patient:ObjectId("518ee0bc9be1909012000002") }

{ _id: ObjectId("518ee0bc9be1909012000002"), date: ISODate("2013-05-13T22:00:00Z"), patient:ObjectId("518ee0bc9be1909012000002") }

{ _id: ObjectId("518ee0bc9be1909012000002"), date: ISODate("2013-05-13T22:00:00Z"), patient:ObjectId("518ee0bc9be1909012000002") }

다음과 같은 결과를 얻기 위해 집계를 사용하였습니다.

{date: ISODate("2013-05-13T22:00:00Z"),
patients:[ObjectId("518ee0bc9be1909012000002"),ObjectId("518ee0bc9be1909012000002"),ObjectId("518ee0bc9be1909012000002")] }

다음과 같습니다.

Appointments.aggregate([
{$group: {_id: '$date', patients: {$push: '$patient'}}},
{$project: {date: '$_id', patients: 1, _id: 0}}
], ...)

이 문서를 저장했는데 작동하지 않는 환자 문서를 채우려면 어떻게 해야 합니까? Appointments.find({}).populate("patient").aggregate....

즉, 동일한 문장에서 poople과 aggregate를 사용할 수 있습니까?

아무쪼록 도와 주세요

최신 버전의 mongoose(mongoose > = 3.6)에서는 두 번째 쿼리가 필요하며 다른 방법으로 채우기를 사용합니다.집약 후 다음 작업을 수행합니다.

Patients.populate(result, {path: "patient"}, callback);

자세한 내용은 Mongoose APIMongoose 문서를 참조하십시오.

편집: 최신 Mongoose API에 새로운 방법이 있는 것 같습니다(위 답변 참조:https://stackoverflow.com/a/23142503/293492)).

아래 오래된 답변

$lookup을 사용할 수 있습니다.이것은 poople과 비슷합니다.

관련 없는 예에서는 $match를 사용하여 레코드를 조회하고 $lookup을 사용하여 외부 모델을 이들 레코드의 서브속성으로 채웁니다.

  Invite.aggregate(
      { $match: {interview: req.params.interview}},
      { $lookup: {from: 'users', localField: 'email', foreignField: 'email', as: 'user'} }
    ).exec( function (err, invites) {
      if (err) {
        next(err);
      }

      res.json(invites);
    }
  );

한 문장이 아니라 두 문장으로 해야 합니다.

비동기 대기 시나리오에서는 입력될 때까지 기다립니다.

const appointments = await Appointments.aggregate([...]);

await Patients.populate(appointments, {path: "patient"});

return appointments;

또는 (제한할 경우)

await Patients.populate(appointments, {path: "patient",  select:  {_id: 1, fullname: 1}});

다음과 같은 하나의 쿼리로 수행할 수 있습니다.

Appointments.aggregate([{
        $group: {
            _id: '$date',
            patients: {
                $push: '$patient'
            }
        }
    },
    {
        $project: {
            date: '$_id',
            patients: 1,
            _id: 0
        }
    },
    {
        $lookup: {
            from: "patients",
            localField: "patient",
            foreignField: "_id",
            as: "patient_doc"
        }
    }
])

poople은 기본적으로 후드 아래에 $120을 사용합니다.이 경우 두 번째 쿼리가 필요하지 않습니다.자세한 내용은 MongoDB 집계를 참조하십시오.

$lookup을 사용하여 가입 실행

수집 주문에는 다음 문서가 포함됩니다.

{ "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2 }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1 }
{ "_id" : 3  }

다른 컬렉션 인벤토리에는 다음 문서가 포함되어 있습니다.

{ "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 }
{ "_id" : 2, "sku" : "def", description: "product 2", "instock" : 80 }
{ "_id" : 3, "sku" : "ijk", description: "product 3", "instock" : 60 }
{ "_id" : 4, "sku" : "jkl", description: "product 4", "instock" : 70 }
{ "_id" : 5, "sku": null, description: "Incomplete" }
{ "_id" : 6 }

주문 수집에 대한 다음 집계 작업은 주문 수집의 필드 항목과 인벤토리 수집의 SKU 필드를 사용하여 주문의 문서를 인벤토리 수집의 문서와 결합합니다.

db.orders.aggregate([
    {
      $lookup:
        {
          from: "inventory",
          localField: "item",
          foreignField: "sku",
          as: "inventory_docs"
        }
   }
])

이 작업은 다음 문서를 반환합니다.

{
  "_id" : 1,
   "item" : "abc",
  "price" : 12,
  "quantity" : 2,
  "inventory_docs" : [
    { "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120       }
  ]
 }
{
  "_id" : 2,
  "item" : "jkl",
  "price" : 20,
  "quantity" : 1,
  "inventory_docs" : [
    { "_id" : 4, "sku" : "jkl", "description" : "product 4", "instock" : 70 }
  ]
}
{
  "_id" : 3,
  "inventory_docs" : [
    { "_id" : 5, "sku" : null, "description" : "Incomplete" },
    { "_id" : 6 }
  ]
}

참조 $lookup

간단한 답변:그럴수는 없어요.

장황한 답변:Aggregation Framework에서 반환된 필드는 사용자에 의해 작성되며 문서 등록 정보를 "이름 변경"할 수 있습니다.

즉, Mongoose는 최종 결과에서 참조된 문서를 사용할 수 있는지 확인할 수 없습니다.

이러한 상황에서는 쿼리가 반환된 후 원하는 필드에 정보를 입력하는 것이 가장 좋습니다.네, 두 번의 DB 호출이 발생하지만, MongoDB가 가능하게 하는 것은 이것입니다.

약간 이런 느낌:

Appointments.aggregate([ ... ], function( e, result ) {
  if ( e ) return;

  // You would probably have to do some loop here, as probably 'result' is array
  Patients.findOneById( result.patient, function( e, patient ) {
    if ( e ) return;

    result.patient = patient;
  });
});

여기에 이미지 설명 입력

domain.Farm.aggregate({
    $match: {
        "_id": mongoose.Types.ObjectId(farmId)
    }
}, {
    $unwind: "$SelfAssessment"
}, {
    $match: {
        "SelfAssessment.questionCategoryID": QuesCategoryId,
        "SelfAssessment.questionID": quesId
    }
},function(err, docs) {
      var options = {
          path: 'SelfAssessment.actions',
          model: 'FarmAction'
     };
     domain.Farm.populate(docs, options, function (err, projects) {
       callback(err,projects);

      });

});

결과 액션 모델을 채웁니다.

{   "error": false,   "object": [
    {
      "_id": "57750cf6197f0b5137d259a0",
      "createdAt": "2016-06-30T12:13:42.299Z",
      "updatedAt": "2016-06-30T12:13:42.299Z",
      "farmName": "abb",
      "userId": "57750ce2197f0b5137d2599e",
      "SelfAssessment": {
        "questionName": "Aquatic biodiversity",
        "questionID": "3kGTBsESPeYQoA8ae2Ocoy",
        "questionCategoryID": "5aBe7kuYWIEoyqWCWcAEe0",
        "question": "Waterways protected from nutrient runoff and stock access through fencing, buffer strips and off stream watering points",
        "questionImage": "http://images.contentful.com/vkfoa0gk73be/4pGLv16BziYYSe2ageCK04/6a04041ab3344ec18fb2ecaba3bb26d5/thumb1_home.png",
        "_id": "57750cf6197f0b5137d259a1",
        "actions": [
          {
            "_id": "577512c6af3a87543932e675",
            "createdAt": "2016-06-30T12:38:30.314Z",
            "updatedAt": "2016-06-30T12:38:30.314Z",
            "__v": 0,
            "Evidence": [],
            "setReminder": "",
            "description": "sdsdsd",
            "priority": "High",
            "created": "2016-06-30T12:38:30.312Z",
            "actionTitle": "sdsd"
          }
        ],
        "answer": "Relevant"
      },
      "locations": []
    }   ],   "message": "",   "extendedMessage": "",   "timeStamp": 1467351827979 }

많은 답변이 있는 것 같습니다.저는 mongoldb에 처음 온 사람이고, 제 답변도 공유하고 싶습니다.조회와 함께 집계 기능을 사용하여 환자를 채우고 있습니다.쉽게 읽을 수 있도록 컬렉션과 필드 이름을 변경했습니다.

도움이 됐으면 좋겠네요.

DB:

db={
  "appointmentCol": [
    {
      _id: ObjectId("518ee0bc9be1909012000001"),
      date: ISODate("2013-05-13T22:00:00Z"),
      patientId: ObjectId("518ee0bc9be1909012000001")
    },
    {
      _id: ObjectId("518ee0bc9be1909012000002"),
      date: ISODate("2013-05-13T22:00:00Z"),
      patientId: ObjectId("518ee0bc9be1909012000002")
    },
    {
      _id: ObjectId("518ee0bc9be1909012000003"),
      date: ISODate("2013-05-13T22:00:00Z"),
      patientId: ObjectId("518ee0bc9be1909012000003")
    }
  ],
  "patientCol": [
    {
      "_id": ObjectId("518ee0bc9be1909012000001"),
      "name": "P1"
    },
    {
      "_id": ObjectId("518ee0bc9be1909012000002"),
      "name": "P2"
    },
    {
      "_id": ObjectId("518ee0bc9be1909012000003"),
      "name": "P3"
    },
    
  ]
}

조회를 사용한 집계 쿼리:

db.appointmentCol.aggregate([
  {
    "$lookup": {
      "from": "patientCol",
      "localField": "patientId",
      "foreignField": "_id",
      "as": "patient"
    }
  }
]) 

출력:

[
  {
    "_id": ObjectId("518ee0bc9be1909012000001"),
    "date": ISODate("2013-05-13T22:00:00Z"),
    "patient": [
      {
        "_id": ObjectId("518ee0bc9be1909012000001"),
        "name": "P1"
      }
    ],
    "patientId": ObjectId("518ee0bc9be1909012000001")
  },
  {
    "_id": ObjectId("518ee0bc9be1909012000002"),
    "date": ISODate("2013-05-13T22:00:00Z"),
    "patient": [
      {
        "_id": ObjectId("518ee0bc9be1909012000002"),
        "name": "P2"
      }
    ],
    "patientId": ObjectId("518ee0bc9be1909012000002")
  },
  {
    "_id": ObjectId("518ee0bc9be1909012000003"),
    "date": ISODate("2013-05-13T22:00:00Z"),
    "patient": [
      {
        "_id": ObjectId("518ee0bc9be1909012000003"),
        "name": "P3"
      }
    ],
    "patientId": ObjectId("518ee0bc9be1909012000003")
  }
]

놀이터: 몽고플레이그라운드그물

대신 lookup을 사용했는데 잘 작동했어요.아래에 표시된 코드를 참조하십시오.

Post.aggregate([
        {
            $group: {
                // Each `_id` must be unique, so if there are multiple
                // posts with the same category, MongoDB will increment `count`.
                _id: '$category',
                count: { $sum: 1 }
            }
        },
        //from: is collection name in MongoDB, localField are primary and foreign keys in Model.
        {$lookup: {from: 'categories', localField: '_id', foreignField:'_id', as: 'category'}}
    ]).then(categoryCount => {
        console.log(categoryCount);
        let json = [];
        categoryCount.forEach(cat => {
            console.log(json);
        });

언급URL : https://stackoverflow.com/questions/16680015/how-to-use-populate-and-aggregate-in-same-statement

반응형