web-dev-qa-db-ja.com

null値を除くmongoのグループ

ドキュメントに対してグループ操作を行うmongoクエリがあります。

空またはnull値なしで結果を絞り込みたい以外は、ほぼ期待どおりの結果が得られました。

現在、私のクエリは次のようになります。

db.productMetadata.aggregate([{$group:{"_id":{"color":"$productAttribute.colour","gender":"$productAttribute.gender"},"count" : {$sum : 1}}}]);

結果は次のようになります。

{ "_id" : { "color" : "BLUE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : {  }, "count" : 4 }
{ "_id" : { "color" : "NA", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "color" : "BLACK", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "gender" : "MEN" }, "count" : 2 }
{ "_id" : { "color" : "BEIGE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "MEN" }, "count" : 1 }

DBの実際のデータでgroup byフィールドの値が空またはnullの場合、行を削除したいと思います。

例外の結果は次のようになります。

{ "_id" : { "color" : "BLUE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "NA", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "color" : "BLACK", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "WOMEN" }, "count" : 1 }
{ "_id" : { "color" : "BEIGE", "gender" : "MEN" }, "count" : 1 }
{ "_id" : { "color" : "BROWN", "gender" : "MEN" }, "count" : 1 }
17
starkk92

追加の_$match_パイプラインステップが必要で、埋め込みフィールド_"$productAttribute.colour"_存在し、nullでない:

_    db.productMetadata.aggregate([
    { 
        "$match": {
            "productAttribute.colour": { 
                "$exists": true, 
                "$ne": null 
            }
        }    
    },
    { 
        "$group": {
            "_id": {
                "color": "$productAttribute.colour",
                "gender": "$productAttribute.gender"
            },
            "count": { 
                "$sum": 1 
            }
        }   
    }        
]);
_
28
chridam

おそらく、$ group操作の前に$ match:{'color':{$ exists:true}}を使用する必要があります。スパースインデックスを使用すると、かなり高速に動作します。また、コレクションに「null」フィールドをまったく格納しないでください。これにより、データベースのサイズが小さくなり、 sparse インデックスの検索速度が向上します(インデックス内のドキュメントが少ない->より高速)

0
Sergey Mazur

この例には2つの異なるコレクションが含まれています。これには集約関数を使用します。私はMongooseも使用しています

  1. $ lookupでcustomfiellabelsを使用してcusmtomfieldに参加しています
  2. $ unwindで配列をフラット化します
  3. $ matchを使用して、テキストにINACTIVEが含まれる名前を除外します(私はREGEXを使用しています)
  4. クライアントで適切に表示されるようにフィールドの名前を変更する$ project

    。 async getAllMasterDataCustomFields(req){

        let response = {};
        try {
    
          response = await customfieldsModel.aggregate([
            {
              $lookup: {
                from: 'customfieldlabels',
                localField: 'cfId',
                foreignField: 'cfId',
                as: 'info'
              }
            },
            { '$unwind': { 'path': '$info', 'preserveNullAndEmptyArrays': true } },
            { '$match': { 'childs.name': { $not: /INACTIVE/ }}},
            {
              $project: {
                'cfId': 1,
                'label': '$info.label',
                'type': '$info.type',
                'childs': 1
              }
            }]).exec();
    
        } catch (e) {
          logger.log('error', `Error while getting response ${e.meesage}`);
        }
    
        return response;
      }
    

0