2017-08-01 7 views
1
{ 
    "_id" : ObjectId("59786a62a96166007d7e364dsadasfafsdfsdgdfgfd"), 
    "someotherdata" : { 
    "place1" : "lwekjfrhweriufesdfwergfwr", 
    "place2" : "sgfertgryrctshyctrhysdthc ", 
    "place3" : "sdfsdgfrdgfvk", 
    "place4" : "asdfkjaseeeeeeeeeeeeeeeeefjnhwklegvds." 
    } 
} 

私のコレクションには何千ものものがあります。私は(一部のレコードで私はplace1なくplace4を持っている) コレクションのキーのデータの最大長の検索

  • (文字列の長さの点で)最長のレコードを検索し、すべてのsomeotherdataに目を通すと、それが存在するかどうかを確認するために、次の

    1. チェックを行う必要があります

    出力はので、新しいへのアクセスを持っていないMongoDBの3.2.9を使用して、この(最長ための文字の数を示す)

    { 
        place1: 123, 
        place2: 12, 
        place3: 17 
        place4: 445 
    } 
    

    I'amのようなものを見なければなりません集約関数。しかし、私はモンゴブシェルを持っています

    編集:私はコレクション全体を通して最長を欲しいと思います。そのため、1000個のドキュメントが存在する可能性がありますが、コレクション全体で各フィールドの長さが最長の結果が1つだけです。

  • +0

    で値を出力する '$ strLenBytes'または' $ strLenCP'にアクセスしないと、 'mapReduce'を使用してJavaScript関数を使って各プロパティの長さを返す必要があります。コレクション全体を通して「各キーの最長の長さ」、または「ドキュメントごとの各キーの長さ」だけを要求しているのか、それとも実際に出力が必要なのかは分かりません。たとえば、4つのキーがあり、3の出力のみのドキュメントを表示します。 –

    +0

    @NeilLunn私の回答を編集しました – 32423hjh32423

    答えて

    1

    各キーの最大値まで減少させるために、このために使用.mapReduce()

    基本的に減少」で、各文書のサブ文書のパス内の各キー本の "length"を発し、
    db.collection.mapReduce(
        function() { 
        emit(null, 
         Object.keys(this.someotherdata).map(k => ({ [k]: this.someotherdata[k].length })) 
         .reduce((acc,curr) => Object.assign(acc,curr),{}) 
        ); 
        }, 
        function(key,values) { 
        var result = {}; 
        values.forEach(value => { 
         Object.keys(value).forEach(k => { 
         if (!result.hasOwnProperty(k)) 
          result[k] = 0; 
         if (value[k] > result[k]) 
          result[k] = value[k]; 
         }); 
        }); 
        return result; 
        }, 
        { 
        "out": { "inline": 1 }, 
        "query": { "someotherdata": { "$exists": true } } 
        } 
    ) 
    

    "、各キーの最大の"length"のみが実際に返されます。

    mapReduceでは、多数のドキュメントを処理する方法が段階的なバッチで「削減」されるため、同じ構造を配置する必要があることに注意してください。だから私たちはemitの数値形式で、"reduce"のように機能します。

    この出力は、質問に示されているドキュメントに表示されます。もちろん、それがコレクションのすべてのドキュメントの "最大値"です。興味のために

    { 
         "_id" : null, 
         "value" : { 
          "place1" : 25.0, 
          "place2" : 26.0, 
          "place3" : 13.0, 
          "place4" : 38.0 
         } 
        } 
    

    、質問の内容は、MongoDBの3.4の特徴は、それらに利用できなかったという事実です。同じ出力で

    db.collection.aggregate([ 
        { "$match": { "someotherdata": { "$exists": true } } }, 
        { "$project": { 
        "_id": 0, 
        "someotherdata": { 
         "$map": { 
         "input": { "$objectToArray": "$someotherdata" }, 
         "as": "s", 
         "in": { "k": "$$s.k", "v": { "$strLenCP": "$$s.v" } } 
         } 
        } 
        }}, 
        { "$unwind": "$someotherdata" }, 
        { "$group": { 
        "_id": "$someotherdata.k", 
        "v": { "$max": "$someotherdata.v" }  
        }}, 
        { "$sort": { "_id": 1 } }, 
        { "$group": { 
        "_id": null, 
        "data": { 
         "$push": { "k": "$_id", "v": "$v" } 
        }  
        }}, 
        { "$replaceRoot": { 
        "newRoot": { 
         "$arrayToObject": "$data" 
        } 
        }} 
    ]) 
    

    { 
        "place1" : 25, 
        "place2" : 26, 
        "place3" : 13, 
        "place4" : 38 
    } 
    
    +0

    ROBO 3T mongoシェルで実行すると、「エラー:行6:予期しないトークンです」と表示されます。 – 32423hjh32423

    +0

    @ 32423hjh32423マイ・バッド。カッコがありません。 –

    +0

    スクリプトの実行に失敗しました。 エラーマップが失敗低減:{ \t "OK":0、 \t "ERRMSG":「はTypeError:this.someotherdata [k]がヌルである:\ n_funcs1/<@:3:45 \ n_funcs1 @:3: 7 \ n」は、 \t "コード":139 } [email protected]/mongo/shell/utils.js:25:13 [email protected]/mongo/shell/collection.js:1411: 1 @(シェル):1:1 – 32423hjh32423

    0

    使用cursor.forEachコレクションを反復処理するのではなく、機能が用意されてい.aggregate()を使用して同じことを行います。 最長の場所を把握してください。nの値(-1から始まり、見つかった場合は更新)。 print()またはprintjson()

    関連する問題