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

Optimalizace dotazů MongoDB

To, co chcete, je výsledek „fazetového vyhledávání“, kde budete mít statistiky o odpovídajících výrazech v aktuální sadě výsledků. Následně, i když existují produkty, které „zdají se“ dělat veškerou práci v jediné odpovědi, musíte vzít v úvahu, že většina generických úložišť bude potřebovat více operací.

S MongoDB můžete použít dva dotazy k získání samotných výsledků a další k získání informací o aspektech. To by poskytlo podobné výsledky jako fasetové výsledky dostupné z produktů specializovaných vyhledávačů, jako je Solr nebo ElasticSearch.

Ale aby to bylo efektivní, chcete to zahrnout do svého dokumentu způsobem, který lze efektivně použít. Velmi efektivní formou pro to, co chcete, je použití pole tokenizovaných dat:

 {
     "otherData": "something",
     "facets": [
         "country:UK",
         "city:London-UK",
         "genre:Student"
     ]
 }

"Fakty" jsou tedy jedno pole ve vašem dokumentu a ne na více místech. Díky tomu je indexování a dotazování velmi snadné. Poté můžete efektivně agregovat své výsledky a získat celkové součty pro každý aspekt:

User.aggregate(
    [
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

Nebo ideálněji s některými kritérii v $match :

User.aggregate(
    [
        { "$match": { "facets": { "$in": ["genre:student"] } } },
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

Nakonec dá odpověď jako:

{ "_id": "country:FR", "count": 50 },
{ "_id": "country:UK", "count": 300 },
{ "_id": "city:London-UK", "count": 150 },
{ "_id": "genre:Student": "count": 500 }

Takovou strukturu lze snadno procházet a kontrolovat, zda se v ní nenacházejí věci, jako je samostatná „země“ a „město“, které patří „země“, protože tato data jsou pouze konzistentně oddělena pomlčkou „-“.

Pokoušet se sbalit dokumenty v polích je špatný nápad. Je také třeba respektovat limit velikosti BSON 16 MB, ze kterého výsledkem sloučení (zejména pokud se snažíte zachovat obsah dokumentu) bude s největší pravděpodobností překročení v odpovědi.

U něčeho tak jednoduchého, jako je získání „celkového počtu“ výsledků z takového dotazu, stačí sečíst prvky konkrétního typu fasety. Nebo jednoduše zadejte stejné argumenty dotazu pro .count() operace:

User.count({ "facets": { "$in": ["genre:Student"] } },function(err,count) {

});

Jak zde bylo řečeno, zejména při implementaci „stránkování“ výsledků, pak jsou role získávání „Počet výsledků“, „Počty faset“ a skutečná „Stránka s výsledky“ delegovány na „oddělené“ dotazy na server.

Není nic špatného na tom, že každý z těchto dotazů odešlete na server paralelně a poté zkombinujete strukturu, která se přidá do vaší šablony nebo aplikace, která vypadá podobně jako fasetovaný výsledek vyhledávání z některého z produktů vyhledávače, který nabízí tento druh odpovědi.

Na závěr

Vložte tedy do dokumentu něco pro označení fazet na jednom místě. Pro tento účel dobře funguje pole tokenizovaných řetězců. Funguje také dobře s formuláři dotazů, jako je $in a $all pro podmínky „nebo“ nebo „a“ u kombinací výběru faset.

Nesnažte se rozmixovat výsledky nebo vnořit doplňky jen proto, aby odpovídaly nějaké vnímané hierarchické struktuře, ale spíše procházejte získané výsledky a používejte jednoduché vzory v tokenech. Je to velmi jednoduché

Spusťte stránkované dotazy na obsah jako samostatné dotazy buď na aspekty, nebo na celkový počet. Pokoušet se vložit veškerý obsah do polí a pak jej omezit, jen abyste získali počty, nedává smysl. Totéž platí pro řešení RDBMS, kde se počítá výsledek stránkování a aktuální stránka jsou samostatné operace dotazu.

Na blogu MongoDB je napsáno více informací o Faceted Search with MongoDB, které také vysvětluje některé další možnosti. Jsou zde také články o integraci s externími vyhledávacími řešeními pomocí mongoconnectoru nebo jiných přístupů.




  1. Proč byste měli stále používat úložiště MMAPv1 pro MongoDB

  2. Vizualizace topologie vašeho clusteru v ClusterControl

  3. Jak mohu vytvořit program pomocí c++ ovladače mongodb?

  4. Jak začít s automatizací databází