복붙노트

[MONGODB] $ 슬라이스 연산자를 사용하여 배열의 마지막 요소를 얻을 수 있습니다

MONGODB

$ 슬라이스 연산자를 사용하여 배열의 마지막 요소를 얻을 수 있습니다

어떻게하여 MongoDB의 조건에 따라 배열의 마지막 요소를 얻으려면?

나는 슬라이스를 사용할 수 없습니다입니다. 여기 내 입력은 다음과 같습니다

{ "1" : { "relevancy" : [  "Y" ] } }
{ "1" : { "relevancy" : [  "Y",  "Y" ] } }
{ "1" : { "relevancy" : [  "N" ] } }
{ "1" : { "relevancy" : [  "Y",  "Y" ] } }
{ "1" : { "relevancy" : [  "Y",  "N" ] } }
{ "1" : { "relevancy" : [  "N" ] } }
{ "1" : { "relevancy" : [  "Y",  "N" ] } }

I는 "관련성"배열의 마지막 요소로서 "Y"를 가지는 행의 수를 카운트 할.

상기 입력은 상기 레코드, 그것은 3이어야한다.

해결법

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

    1.당신이 지금 알고있는 바와 같이, $ 슬라이스는 시험 결과에 반환 된 배열 요소를 제한하는 투사에 사용됩니다. 당신은 발견에서 결과 프로그램 목록을 처리와 붙어 될 것이다 그래서 ().

    당신이 지금 알고있는 바와 같이, $ 슬라이스는 시험 결과에 반환 된 배열 요소를 제한하는 투사에 사용됩니다. 당신은 발견에서 결과 프로그램 목록을 처리와 붙어 될 것이다 그래서 ().

    더 나은 방법은 골재 사용하는 것입니다. 그러나 처음의이 $ 슬라이스가 사용되는 방법을 살펴 보자 :

    > db.collection.find({},{ relevancy: {$slice: -1} })
    { "_id" : ObjectId("530824b95f44eac1068b45c0"), "relevancy" : [  "Y" ] }
    { "_id" : ObjectId("530824b95f44eac1068b45c2"), "relevancy" : [  "Y" ] }
    { "_id" : ObjectId("530824b95f44eac1068b45c3"), "relevancy" : [  "N" ] }
    { "_id" : ObjectId("530824b95f44eac1068b45c4"), "relevancy" : [  "Y" ] }
    { "_id" : ObjectId("530824b95f44eac1068b45c6"), "relevancy" : [  "N" ] }
    { "_id" : ObjectId("530824b95f44eac1068b45c7"), "relevancy" : [  "N" ] }
    { "_id" : ObjectId("530824b95f44eac1068b45c8"), "relevancy" : [  "N" ] }
    

    당신은 마지막 배열 요소를 얻을 수 있지만, 당신은 당신이 마지막 요소 값과 일치 할 수 없기 때문에 결과를 루프에 붙어있다 그래서. 당신은뿐만 아니라 단지 코드에서 이런 짓을했을 수도 있습니다.

    이제 집계를 살펴 보자 :

    db.collection.aggregate([
        // Match things so we get rid of the documents that will never match, but it will
        // still keep some of course since they are arrays, that *may* contain "N"
        { "$match": { "relevancy": "Y" } },
    
        // De-normalizes the array
        { "$unwind": "$relevancy" },
    
        // The order of the array is retained, so just look for the $last by _id
        { "$group": { "_id": "$_id", "relevancy": { "$last": "$relevancy" } }},
    
        // Match only the records with the results you want
        { "$match": { "relevancy": "Y" }},
    
        // Oh, and maintain the original _id order [ funny thing about $last ]
        { "$sort": { "_id": 1 } }
    ])
    

    이 집계 ()의 첫 번째 사용 될 경우에도, 나는 그것을 배울 것이 좋습니다. 그것은 아마도 가장 유용한 문제 해결 도구입니다. 물론 나를 위해왔다. 당신이 배우는 경우 한 번에 한 번 각 단계를 넣습니다.

    또한하지 않도록 문서 양식, 모두가 1 : {...} 하위 문서 표기 실수로 나타납니다하지만 당신은을 지우거나 대신 참조 "1.relevancy"에 위의 코드를 조정해야합니다. 나는 당신의 문서가 실제로 더이 생각처럼 희망 :

    { "relevancy" : [  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c0") }
    { "relevancy" : [  "Y",  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c2") }
    { "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c3") }
    { "relevancy" : [  "Y",  "Y" ], "_id" : ObjectId("530824b95f44eac1068b45c4") }
    { "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c6") }
    { "relevancy" : [  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c7") }
    { "relevancy" : [  "Y",  "N" ], "_id" : ObjectId("530824b95f44eac1068b45c8") }
    

    물론 MongoDB를 3.2을 소개합니다 $ 슬라이스에 대한 "통합"연산자 및 $ 긴장을 풀고 $ 그룹 처리에 대한 필요성을 제거하는 더 나은 $ arrayElemAt 연산자. 당신은 단지 $ 편집하다와 "논리적 일치"를 만들 쿼리 초기 $ 경기 후 :

    db.collection.aggregate([
        { "$match": { "relevancy": "Y" } },
        { "$redact": {
            "$cond": {
                "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
                "then": "$$KEEP",
                "else": "$$PRUNE"
            }
        }}   
    ])
    

    즉, 반환 된 결과에서 문서 $$ KEEP 또는 $$ PRUNE 여부를 결정할 때 배열의 마지막 요소에 검사를 할 것입니다.

    당신은 여전히 ​​"투사"를 원하는 경우에 당신은 실제로 $ 슬라이스를 추가 할 수 있습니다 :

    db.collection.aggregate([
        { "$match": { "relevancy": "Y" } },
        { "$redact": {
            "$cond": {
                "if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
                "then": "$$KEEP",
                "else": "$$PRUNE"
            }
        }},
        { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } }
    ])
    

    또는의 다른 방법 :

    db.collection.aggregate([
        { "$match": { "relevancy": "Y" } },
        { "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } },
        { "$match": { "relevancy": "Y" } }
    ])
    

    그러나 먼저 $의 편집하다을하고 "다음"$ 프로젝트`의 모든 재 형성을 할 아마도 적은 비용이다.

  2. ==============================

    2.몽고 4.4부터는 집합 연산자 $의 마지막 액세스 배열의 마지막 요소를 사용할 수있다 :

    몽고 4.4부터는 집합 연산자 $의 마지막 액세스 배열의 마지막 요소를 사용할 수있다 :

    // { "1": { "relevancy": ["Y"] } }
    // { "1": { "relevancy": ["Y", "Y"] } }
    // { "1": { "relevancy": ["N"] } }
    // { "1": { "relevancy": ["Y", "Y"] } }
    // { "1": { "relevancy": ["Y", "N"] } }
    // { "1": { "relevancy": ["N"] } }
    // { "1": { "relevancy": ["Y", "N"] } }
    db.collection.aggregate([
      { $project: { last: { $last: "$1.relevancy" } } },
      // { "last": "Y" }
      // { "last": "Y" }
      // { "last": "N" }
      // { "last": "Y" }
      // { "last": "N" }
      // { "last": "N" }
      // { "last": "N" }
      { $match: { "last": "Y" } },
      // { "last": "Y" }
      // { "last": "Y" }
      // { "last": "Y" }
      { $count: "result" }
      // { "result" : 3 }
    ])
    
  3. from https://stackoverflow.com/questions/21952005/using-slice-operator-to-get-last-element-of-array by cc-by-sa and MIT license