2017-03-21 1 views
2

Angenommen, ich habe Struktur als;

{ 
    "class" : "TESTCLASS", 
    "id" : "HyvF1sdZl", 
    "depends" : [ 
     "S11T5ce", 
     "BytQLN6ml", 
     "Byzz8Ea7l", 
     "r1TUNX58x" 
    ], 
    "list" : [ 
     { 
      "class" : "DATA", 
      "id" : "H113d5Pwx" 
     }, 
     { 
      "class" : "DATA", 
      "id" : "H113d5Pwx" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "DATA", 
      "id" : "H113d5Pwx" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "YENITEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN_", 
      "id" : "Byzz8Ea7l" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     } 
    ] 
} 

Ich möchte projectlist Elemente, deren id ‚s sind in depends Array enthalten.

Ich meine, ich will nur bekommen;

"depends" : [ 
    "S11T5ce", 
    "BytQLN6ml", 
    "Byzz8Ea7l", 
    "r1TUNX58x" 
], 
"list" : [ 
    { 
     "class" : "FDSAFAS", 
     "id" : "S11T5ce" 
    }, 
    { 
     "class" : "EN", 
     "id" : "BytQLN6ml" 
    }, 
    { 
     "class" : "EN_", 
     "id" : "Byzz8Ea7l" 
    }, 
    { 
     "class" : "TEST", 
     "id" : "r1TUNX58x" 
    } 

] 

Um dies tun zu können, habe ich geschrieben;

db.definition.aggregate([ 
    { 
     $project: { 
      _id: 0, 
      depends :1, 
      depends: {$in: ["$list.id"]}, 
      "list.defid": 1, 
      "list.class" :1, 
     } 

    } 
]).pretty() 

Aber das wirft einen Fehler als "errmsg" : "Expression $in takes exactly 2 arguments. 1 were passed in."

Was bin ich?

Antwort

1

Mit MongoDB 3.4 Sie die $addFields Pipeline nutzen könnten andere Felder zu projizieren, ohne sie explizit zu benennen. Als eine einzige Pipeline, verwendet eine Kombination aus den $setUnion, $filter und $in Betreibern den gewünschten Array zurückzubringen. Der Bediener $setUnion hilft bei der Eliminierung von Duplikaten, bevor er den Operator $filter anwendet.

der Intuition zu folgen, läßt dieses Beispiel Pipeline folgen, die mit den $filter Betreibern laufen gerade:

db.collection.aggregate([ 
    { 
     "$addFields": { 
      "list": { 
       "$filter": { 
        "input": "$list", 
        "as": "item", 
        "cond": { "$in": ["$$item.id", "$depends"] }      
       } 
      } 
     } 
    } 
]) 

Beispielausgabe

{ 
    "_id" : ObjectId("58d0e0d97a3871921504bb69"), 
    "class" : "TESTCLASS", 
    "id" : "HyvF1sdZl", 
    "depends" : [ 
     "S11T5ce", 
     "BytQLN6ml", 
     "Byzz8Ea7l", 
     "r1TUNX58x" 
    ], 
    "list" : [ 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "YENITEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN_", 
      "id" : "Byzz8Ea7l" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     }, 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     } 
    ] 
} 

Mit dem $setUnion Operator, Dubletten werden zuerst eliminiert, bevor angewendet wird als:

db.collection.aggregate([ 
    { 
     "$addFields": { 

      "list": { 
       "$filter": { 
        "input": { "$setUnion": ["$list", []] }, 
        "as": "item", 
        "cond": { "$in": ["$$item.id", "$depends"] }      
       }     
      }    
     } 
    } 
]) 

Beispielausgabe

{ 
    "class" : "TESTCLASS", 
    "id" : "HyvF1sdZl", 
    "depends" : [ 
     "S11T5ce", 
     "BytQLN6ml", 
     "Byzz8Ea7l", 
     "r1TUNX58x" 
    ], 
    "list" : [ 
     { 
      "class" : "FDSAFAS", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "TEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "YENITEST", 
      "id" : "r1TUNX58x" 
     }, 
     { 
      "class" : "EN_", 
      "id" : "Byzz8Ea7l" 
     }, 
     { 
      "class" : "CALENDAR", 
      "id" : "S11T5ce" 
     }, 
     { 
      "class" : "EN", 
      "id" : "BytQLN6ml" 
     } 
    ] 
} 
+1

In MongoDB 3.4 sollten Sie das ['$ in'] (https: //docs.mongodb.com/manual/reference/operator/aggregation/in /) aggregationsoperator anstelle von $ setIsSubset – styvane

+0

@ M.StyvaneSoukossi In der Tat! Danke für den Zeiger – chridam

1

Sie können zunächst $project und $filter verwenden, um Objekte zu filtern, wo id nicht in depends Array ist dann aber einzigartige Objekte von id zurückzukehren und schließen auch Klasse ein bisschen Problem ist, weil, wenn Sie verwenden $addToSet Sie können nicht angeben, Felder dass Sie andere Felder im Objekt oder in diesem Fall class in der Liste ignorieren möchten.

db.col.aggregate([ 
    {$project: { 
     depends: 1, 
     class: 1, 
     list: { 
      $filter: { 
       input: '$list', 
       as: 'item', 
       cond: { 
        $setIsSubset: [['$$item.id'], '$depends'] 
       } 
      } 
     } 
    }}, 
    {$unwind: '$list'}, 
    {$group: { 
     _id: '$_id', 
     depends: {$first: '$depends'}, 
     class: {$first: '$class'}, 
     list: { 
      $addToSet: { 
       id: '$list.id', 
       class: '$list.class' 
      } 
     }, 

    }} 
]) 

Das Endergebnis ist dieses

[{ 
    "_id": "58d0cea6aecf3102684e4f0e", 
    "depends": ["S11T5ce", "BytQLN6ml", "Byzz8Ea7l", "r1TUNX58x"], 
    "class": "TESTCLASS", 
    "list": [{ 
    "id": "Byzz8Ea7l", 
    "class": "EN_" 
    }, { 
    "id": "BytQLN6ml", 
    "class": "EN" 
    }, { 
    "id": "S11T5ce", 
    "class": "FDSAFAS" 
    }, { 
    "id": "r1TUNX58x", 
    "class": "YENITEST" 
    }, { 
    "id": "S11T5ce", 
    "class": "CALENDAR" 
    }, { 
    "id": "r1TUNX58x", 
    "class": "TEST" 
    }] 
}] 
+0

Falls Sie Sie kann man am Ende mehr '$ project' https://jsfiddle.net nicht id in Endergebnisses wollen hinzufügen/Lg0wyt9u/1724/ –