sql >> Database teknologi >  >> NoSQL >> MongoDB

Mongodb multi-indlejret array-søgning

Du skal bruge .aggregate() metode for at "filtrere" ethvert arrayindhold til mere end et enkelt match, og det grundlæggende match er også meget enklere, da MongoDB er ligeglad med, at dataene er inden for arrays, bare så længe den angivne sti er korrekt:

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 } }}
])

Med PHP lyder dette som følger:

$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 ) ) )
))

$map operatøren tillader inspektion af hvert element i det ydre array og sendte hvert element til $cond ternær drift. Dette behandler en $setIsSubset operation på det "indre" array for at se, om det faktisk indeholder en af ​​værdierne i det alternative sæt (i dette tilfælde [1] ) og hvor en true evaluering foretages, derefter returneres elementet eller på anden måde false .

Pointen med $setDifference er at fjerne disse false værdier fra det modificerede array og returnerer kun matchede elementer. Og endelig $exists test ser ud for at se, at det ydre array faktisk har mindst ét ​​element og ikke er tomt som følge af filtreringen.

De returnerede dokumenter er dem med den matchende betingelse og kun de array-elementer, der også matcher den angivne betingelse.

Operatørerne her kræver selvfølgelig, at du mindst har MongoDB 2.6 som server (hvilket er en ret gammel udgivelse nu og i det mindste en anbefalet opdatering), men hvis du stadig har en mindre version, har du brug for en traditionel tilgang med $unwind og $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. SQL vs NoSQL for et lagerstyringssystem

  2. mongodb forbindelse timeout fejl

  3. Hvad er brugen af ​​typen javascript/javascriptwithscope af bson

  4. MongoDB atomopdatering via 'flet' dokument