sql >> Database >  >> NoSQL >> MongoDB

Mongodb onderscheiden op een matrixveld met regex-query?

Het aggregatieraamwerk en niet de .distinct() commando:

db.event.aggregate([
    // De-normalize the array content to separate documents
    { "$unwind": "$tags" },

    // Filter the de-normalized content to remove non-matches
    { "$match": { "tags": /foo/ } },

    // Group the "like" terms as the "key"
    { "$group": {
        "_id": "$tags"
    }}
])

Het is waarschijnlijk beter om een ​​"anker" aan het begin van de regex te gebruiken, je bedoelt vanaf het "begin" van de string. En doe dit ook $match voordat u $unwind verwerkt ook:

db.event.aggregate([
    // Match the possible documents. Always the best approach
    { "$match": { "tags": /^foo/ } },

    // De-normalize the array content to separate documents
    { "$unwind": "$tags" },

    // Now "filter" the content to actual matches
    { "$match": { "tags": /^foo/ } },

    // Group the "like" terms as the "key"
    { "$group": {
        "_id": "$tags"
    }}
])

Dat zorgt ervoor dat u $unwind niet verwerkt op elk document in de verzameling en alleen diegene die mogelijk uw "overeenkomende tags"-waarde bevatten voordat u "filtert" om er zeker van te zijn.

De echt "complexe" manier om grote arrays enigszins te verzachten met mogelijke overeenkomsten kost wat meer werk, en MongoDB 2.6 of hoger:

db.event.aggregate([
    { "$match": { "tags": /^foo/ } },
    { "$project": {
        "tags": { "$setDifference": [
            { "$map": {
                "input": "$tags",
                "as": "el",
                "in": { "$cond": [
                    { "$eq": [ 
                        { "$substr": [ "$$el", 0, 3 ] },
                        "foo"
                    ]},
                    "$$el",
                    false
                ]}
            }},
            [false]
        ]}
    }},
    { "$unwind": "$tags" },
    { "$group": { "_id": "$tags" }}
])

Dus $map is een mooie "in-line" processor van arrays, maar het kan maar zo ver gaan. De $setDifference operator negeert de false overeenkomsten, maar uiteindelijk moet je nog steeds $unwind . verwerken om de resterende $group . te doen podium voor verschillende waarden in het algemeen.

Het voordeel hiervan is dat arrays nu worden "gereduceerd" tot alleen het "tags" -element dat overeenkomt. Gebruik dit alleen niet als u een "telling" wilt van de voorkomens wanneer er "meerdere verschillende" waarden in hetzelfde document zijn. Maar nogmaals, er zijn andere manieren om daarmee om te gaan.




  1. Explain() in Mongodb:verschillen tussen nscanned en nscannedObjects

  2. wat is het echte doel van $ref (DBRef) in MongoDb

  3. cryptische mongodb-fout LEFT_SUBFIELD ondersteunt alleen Object:statistieken niet:6

  4. Aan de slag met databaseautomatisering