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

Mongoose – hledejte text ve třech polích na základě skóre nebo váhy

"textový index" a hledat je zde pravděpodobně nejlepší možností, pokud hledáte celá slova.

Přidání textového indexu do definice schématu je poměrně jednoduché:

BookSchema.index(
    {
         "name": "text",
         "description": "text",
         "body": "text"
    },
    {
        "weights": {
            "name": 5,
            "description": 2
        }
    }
)

To vám umožňuje provádět jednoduché vyhledávání s "nastaveným" vážením polí:

Book.find({ "$text": { "$search": "Holiday School Year" } })
    .select({ "score": { "$meta": "textScore" } })
    .sort({ "score": { "$meta": "textScore" } })
    .exec(function(err,result) {

    }
);

Kde se každý výraz shoduje, bude posuzován v porovnání s nalezeným polem, které dává největší váhu a počet výskytů.

Přiřazení vah je připojeno k "indexu", takže definice se provádí jednou a nelze ji změnit. Dalším omezením je, že při „textovém vyhledávání“ se nehledí na „částečná“ slova. Například „ci“ neodpovídá „Město“ nebo „Občan“ a pro takovou věc byste místo toho potřebovali regulární výraz.

Pokud potřebujete větší flexibilitu nebo obecně musíte být schopni dynamicky měnit váhu výsledků, potřebujete něco jako agregační rámec nebo mapReduce.

Agregační rámec však nemůže provést "logickou" shodu operace (může filtrovat přes $match operátor, ale ne "logická" shoda ) "regulárního výrazu" s vašimi podmínkami. Můžete však pracovat s jednotlivými slovy a "přesnými" shodami, pokud to vyhovuje.

Book.aggregate(
    [
        { "$match": {
            "$or": [
                { "name": /Holiday/ },
                { "description": /Holiday/ },
                { "body": /Holiday/ }
            ]
        }},
        { "$project": {
            "name": 1,
            "description": 1,
            "body": 1,
            "score": {
                "$add": [
                    { "$cond": [{ "$eq": [ "$name", "Holiday" ] },5,0 ] },
                    { "$cond": [{ "$eq": [ "$description", "Holiday" ] },2,0 ] },
                    { "$cond": [{ "$eq": [ "$body", "Holiday" ] },1,0 ] }
                ]
            }
        }},
        { "$sort": { "score": -1 } }
    ],
    function(err,results) {

    }
)

Vzhledem k tomu, že agregační kanál používá k dotazování datovou strukturu, kde můžete změnit parametry pro váhu každého provedení na cokoliv, co aktuálně potřebujete.

MapReduce sdílí podobný princip, kdy můžete zahrnout vypočítané "skóre" do části primárního klíče emitovaného jako hlavní prvek. MapReduce přirozeně třídí všechny vstupy vydávané touto klávesou jako optimalizaci pro podávání do funkce snížení. Takový výsledek však nemůžete dále třídit nebo „omezovat“.

To jsou obecně vaše možnosti, na které se můžete podívat a rozhodnout se, co nejlépe vyhovuje vašemu případu.




  1. Nenastavená operace pro model MongoMapper selhala, nelze odstranit / odebrat klíč z modelu

  2. Mongodb šetří o jeden den méně – problém časového pásma

  3. Dotaz selhal s chybovým kódem 13 a chybovou zprávou „není autorizováno [db] k provedení příkazu { find:

  4. pořadí řazení mongodb na _id