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

Mongodb adskilt på et matrixfelt med regex-forespørgsel?

aggregeringsramme og ikke .distinct() kommando:

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

Du er sandsynligvis bedre af at bruge et "anker" til begyndelsen af ​​det regex, du mener fra "starten" af strengen. Og gør også dette $match før du behandler $unwind også:

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

Det sikrer, at du ikke behandler $unwind på hvert dokument i samlingen og kun dem, der muligvis indeholder dine "matchede tags"-værdi, før du "filtrerer" for at være sikker.

Den virkelig "komplekse" måde at afbøde store arrays på med mulige matches noget kræver lidt mere arbejde, og MongoDB 2.6 eller nyere:

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

$map er en dejlig "in-line" processor af arrays, men det kan kun gå så langt. $setDifference operator negerer false matcher, men i sidste ende skal du stadig behandle $unwind for at gøre den resterende $group trin for overordnede distinkte værdier.

Fordelen her er, at arrays nu er "reduceret" til kun "tags"-elementet, der matcher. Bare lad være med at bruge dette, når du vil have en "tælling" af forekomsterne, når der er "flere forskellige" værdier i det samme dokument. Men igen, der er andre måder at håndtere det på.




  1. Sådan kalder du et lagret JavaScript i MongoDb fra C#

  2. Redis nøglerumsmeddelelser med StackExchange.Redis

  3. Gruppér efter tilstand i MongoDB

  4. Skubber element til Mongodb-samlingsmatrix