sql >> Database >  >> NoSQL >> MongoDB

Mongodb multi-geneste array zoeken

Je hebt de .aggregate() nodig methode om elke array-inhoud te "filteren" voor meer dan een enkelvoudige overeenkomst, en ook de basisovereenkomst is een stuk eenvoudiger omdat MongoDB er niet om geeft dat de gegevens zich in arrays bevinden, zolang het opgegeven pad maar correct is:

db.collection.aggregate([
    { "$match": { "data.userid": 1 } },
    { "$project": {
        "data": {
            "$setDifference": [
                { "$map": {
                    "input": "$data",
                    "as": "el",
                    "in": { 
                        "$cond": [
                            { "$setIsSubset": [ [1], "$$el.userid" ] },
                            "$$el",
                            false
                        ]
                    }
                }},
                [false]
            ]
        }
    }},
    { "$match": { "data.0": { "$exists": true } }}
])

Met PHP wordt dit als volgt genoteerd:

$collection->aggregate(array(
    array( '$match' => array( "data.userid" => 1 )),
    array(
        '$project' => array(
            'data' => array(
                '$setDifference' => array(
                    array(
                        '$map' => array(
                            'input' => '$data',
                            'as' => 'el',
                            'in' => array(
                                '$cond' => array(
                                    array( '$setIsSubset' => array(array(1),'$$el.userid') ),
                                    '$$el',
                                    FALSE
                                )
                            )
                        )
                    ),
                    array(FALSE)
                )
            )
        )
    ),
    array( '$match' => array( 'data.0' => array( '$exists' => TRUE ) ) )
))

De $map operator staat inspectie van elk element van de buitenste array toe en geeft elk element door aan de $cond ternaire operatie. Dit verwerkt een $setIsSubset bewerking op de "innerlijke" array om te zien of deze inderdaad een van de waarden in de alternatieve set bevat (in dit geval [1] ) en waar een true evaluatie is gemaakt, dan wordt het element geretourneerd of anders false .

Het punt van $setDifference is om die false . te verwijderen waarden uit de gewijzigde array en retourneert alleen overeenkomende elementen. En tot slot de $exists test kijkt of de buitenste array daadwerkelijk ten minste één element bevat en niet leeg is als gevolg van de filtering.

De geretourneerde documenten zijn die met de overeenkomende voorwaarde en alleen de array-elementen die ook overeenkomen met de opgegeven voorwaarde.

Natuurlijk vereisen de operators hier dat je ten minste MongoDB 2.6 als server hebt (wat nu een vrij oude release is en op zijn minst een geadviseerde update), maar als je nog steeds een mindere versie hebt, dan heb je een traditionele aanpak nodig met $unwind en $group :

$collection->aggregate(array(
    array( '$match' => array( "data.userid" => 1 )),
    array( '$unwind' => '$data' ),
    array( '$match' => array( 'data.userid' => 1 )),
    array( 
        '$group' => array(
            '_id' => '$_id',
            'data' => array( '$push' => '$data' )
        )
    )
))



  1. Geen resultaten met tekst zoeken MongoDB PHP

  2. Inzicht in WriteConcern in MongoDB C#

  3. Django Redis Fout onbekend commando 'BZPOPMIN'

  4. Hoe een document te groeperen en selecteren dat overeenkomt met max binnen elke groep in MongoDB?