sql >> Databáze >  >> NoSQL >> MongoDB

Mongodb odlišný na poli pole s dotazem na regulární výraz?

rámec agregace a ne .distinct() příkaz:

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

Pravděpodobně je lepší použít "kotvu" na začátek regulárního výrazu, máte na mysli od "začátku" řetězce. A také to udělat $match před zpracováním $unwind také:

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

Tím zajistíte, že nezpracováváte $unwind na každém dokumentu ve sbírce a pouze na těch, které případně obsahují hodnotu vašich „odpovídajících značek“, než se přesvědčíte, že je „filtrujete“.

Skutečně "složitý" způsob, jak poněkud zmírnit velká pole možnými shodami, vyžaduje trochu více práce a MongoDB 2.6 nebo vyšší:

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

Takže $map je pěkný "in-line" procesor polí, ale může jít jen tak daleko. $setDifference operátor neguje false shoduje se, ale nakonec stále musíte zpracovat $unwind udělat zbývající $group fázi pro odlišné hodnoty celkově.

Výhodou je, že pole jsou nyní „redukována“ pouze na prvek „tags“, který odpovídá. Jen to nepoužívejte, když chcete "počet" výskytů, když je ve stejném dokumentu "více odlišných" hodnot. Ale opět existují jiné způsoby, jak to zvládnout.




  1. Statistiky databáze a sbírky MongoDB

  2. Redis set vs hash

  3. nastavte výchozí hodnoty na pole mongoose v node js

  4. Příkaz pro reindexaci všech kolekcí mongodb