복붙노트

[MONGODB] 복수는 $ 검색 연산자를 사용하여 조인 조건

MONGODB

복수는 $ 검색 연산자를 사용하여 조인 조건

여기 내 모음입니다 :

collection1 :

{
    user1: 1,
    user2: 2,
    percent: 0.56
}

collection2 :

{
    user1: 1,
    user2: 2,
    percent: 0.3
}

나는 '사용자 1'과 '사용자 2'에 의해 두 개의 모음을 결합 할 수 있습니다.

이 같은 결과 :

{
    user1: 1,
    user2: 2,
    percent1: 0.56,
    percent2: 0.3
}

어떻게 파이프 라인을 작성하려면 어떻게해야합니까?

해결법

  1. ==============================

    1.우리는 여러 버전 3.6 및 최신에서 $ 조회 집계 파이프 라인 연산자와 조건을 가입 할 수 있습니다.

    우리는 여러 버전 3.6 및 최신에서 $ 조회 집계 파이프 라인 연산자와 조건을 가입 할 수 있습니다.

    우리는이 선택적 필드를하게 사용 변수 필드의 값을 할당해야합니다; 당신은 당신이 컬렉션에서 실행할 파이프 라인을 지정하는 파이프 라인 필드 단계에 해당 변수에 액세스 할 수 있습니다.

    은 $ 일치하는 단계에서, 우리는 필드의 값을 비교하기 위해 $의 EXPR 평가 쿼리 연산자를 사용합니다.

    파이프 라인의 마지막 단계는 우리가 단순히 $ mergeObjects 연산자를 사용하여 $$ 루트 문서의 한 부분으로 $ 조회 결과를 병합은 $ replaceRoot 집계 파이프 라인 단계입니다.

    db.collection2.aggregate([
           {
              $lookup: {
                 from: "collection1",
                 let: {
                    firstUser: "$user1",
                    secondUser: "$user2"
                 },
                 pipeline: [
                    {
                       $match: {
                          $expr: {
                             $and: [
                                {
                                   $eq: [
                                      "$user1",
                                      "$$firstUser"
                                   ]
                                },
                                {
                                   $eq: [
                                      "$user2",
                                      "$$secondUser"
                                   ]
                                }
                             ]
                          }
                       }
                    }
                 ],
                 as: "result"
              }
           },
           {
              $replaceRoot: {
                 newRoot: {
                    $mergeObjects:[
                       {
                          $arrayElemAt: [
                             "$result",
                             0
                          ]
                       },
                       {
                          percent1: "$$ROOT.percent1"
                       }
                    ]
                 }
              }
           }
        ]
    )
    

    다음과 같이이 파이프 라인의 수율 뭔가 :

    {
        "_id" : ObjectId("59e1ad7d36f42d8960c06022"),
        "user1" : 1,
        "user2" : 2,
        "percent" : 0.3,
        "percent1" : 0.56
    }
    

    당신은 3.6 버전에 있지 않은 경우, 먼저 당신이 $ 언 와인드 집계 파이프 라인 연산자를 사용하여 일치하는 문서의 배열이 긴장을 풀고에서 다음 "사용자 1"을 가정 해 봅시다 당신의 분야 중 하나를 사용하여 가입 할 수 있습니다. 파이프 라인의 다음 단계는 당신이 "가입"컬렉션에서 "사용자 2"의 값과 입력 문서는 $$를 유지하고 $$ PRUNE 시스템 변수를 사용하여 동일하지 않고 해당 문서를 필터링은 $ 편집하다 단계입니다. 그런 다음 $ 프로젝트 단계에서 문서를 바꿀 수 있습니다.

    db.collection1.aggregate([
        { "$lookup": { 
            "from": "collection2", 
            "localField": "user1", 
            "foreignField": "user1", 
            "as": "collection2_doc"
        }}, 
        { "$unwind": "$collection2_doc" },
        { "$redact": { 
            "$cond": [
                { "$eq": [ "$user2", "$collection2_doc.user2" ] }, 
                "$$KEEP", 
                "$$PRUNE"
            ]
        }}, 
        { "$project": { 
            "user1": 1, 
            "user2": 1, 
            "percent1": "$percent", 
            "percent2": "$collection2_doc.percent"
        }}
    ])
    

    이는 생산 :

    {
        "_id" : ObjectId("572daa87cc52a841bb292beb"),
        "user1" : 1,
        "user2" : 2,
        "percent1" : 0.56,
        "percent2" : 0.3
    }
    

    당신의 컬렉션을 문서가 동일한 구조를 가지고 있고 자신이 자주이 작업을 수행 찾을 경우에, 당신은 하나에 두 개의 컬렉션을 병합하거나 새 컬렉션에 그 컬렉션의 문서를 삽입하는 것이 좋습니다.

    db.collection3.insertMany(
        db.collection1.find({}, {"_id": 0})
        .toArray()
        .concat(db.collection2.find({}, {"_id": 0}).toArray())
    )
    

    "USER1"와 "사용자 2"에 의해 그런 다음 $ 그룹은 문서

    db.collection3.aggregate([
        { "$group": {
            "_id": { "user1": "$user1", "user2": "$user2" }, 
            "percent": { "$push": "$percent" }
        }}
    ])
    

    이는 수율 :

    { "_id" : { "user1" : 1, "user2" : 2 }, "percent" : [ 0.56, 0.3 ] }
    
  2. ==============================

    2.당신이 당신의 데이터를 모델링하기 위해 노력하고 수행 할 수 있습니다 MongoDB를 그렇게 결정하기 전에 여러 필드에 조인 여부를 확인하기 위해 여기에 온 경우에 읽어 보시기 바랍니다.

    당신이 당신의 데이터를 모델링하기 위해 노력하고 수행 할 수 있습니다 MongoDB를 그렇게 결정하기 전에 여러 필드에 조인 여부를 확인하기 위해 여기에 온 경우에 읽어 보시기 바랍니다.

    MongoDB를 조인을 수행 할 수 있지만, 당신은 또한 응용 프로그램의 액세스 패턴에 따라 모델 데이터에 대한 자유가있다. 문제에 제시된 데이터를 간단하게하는 경우, 우리는 단순히 하나의 콜렉션을 유지할 수 다음과 같다 :

    {
        user1: 1,
        user2: 2,
        percent1: 0.56,
        percent2: 0.3
    }
    

    지금 당신은 당신이에 가입하여 수행 한 것이 컬렉션의 모든 작업을 수행 할 수 있습니다. 왜 우리는 조인 피하려고? 그들이 필요할 때 수평 확장에서 당신을 중지하게 분산됩니다 컬렉션 (문서)에 의해 지원되지 않기 때문에. 정규화 된 데이터는 SQL에 아주 잘 작동 (별도의 테이블 / 컬렉션을 가짐), 그러나 몽고에 올 때, 피해는 대부분의 경우에 결과없이 이점을 제공 할 수 있습니다 조인. MongoDB의에서 사용 정상화 만이 다른 선택의 여지가 없을 때. 워드 프로세서 :

    내장 왜 당신이 정상화에 그것을 선택할 것에 대한 자세한 내용을 보려면 여기를 확인하십시오.

  3. ==============================

    3.당신은 $ 일치와 $ 프로젝트 파이프 라인을 사용하여 여러 필드 경기를 할 수 있습니다. (여기에 대한 자세한 대답을 참조 - MongoDB를 여러 분야에 참여하기)

    당신은 $ 일치와 $ 프로젝트 파이프 라인을 사용하여 여러 필드 경기를 할 수 있습니다. (여기에 대한 자세한 대답을 참조 - MongoDB를 여러 분야에 참여하기)

    db.collection1.aggregate([
                        {"$lookup": {
                        "from": "collection2",
                        "localField": "user1",
                        "foreignField": "user1",
                        "as": "c2"
                        }},
                        {"$unwind": "$c2"},
    
                        {"$project": {
                        "user2Eq": {"$eq": ["$user2", "$c2.user2"]},
                        "user1": 1, "user2": 1, 
                        "percent1": "$percent", "percent2": "$c2.percent"
                        }},
    
                        {"$match": {
                        {"user2Eq": {"$eq": True}}
                        }},
    
                        {"$project": {
                        "user2Eq": 0
                        }}
    
                        ])
    
  4. from https://stackoverflow.com/questions/37086387/multiple-join-conditions-using-the-lookup-operator by cc-by-sa and MIT license