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

Procento podmínek NEBO shodných v mongodb

Vaše řešení by skutečně mělo být specifické pro MongoDB, jinak skončíte s výpočty a případným párováním na straně klienta, a to nebude dobré pro výkon.

Takže samozřejmě to, co opravdu chcete, je způsob, jak zajistit zpracování na straně serveru:

db.products.aggregate([

    // Match the documents that meet your conditions
    { "$match": {
        "$or": [
            { 
                "features": { 
                    "$elemMatch": {
                       "key": "Screen Format",
                       "value": "16:9"
                    }
                }
            },
            { 
                "features": { 
                    "$elemMatch": {
                       "key" : "Weight in kg",
                       "value" : { "$gt": "5", "$lt": "8" }
                    }
                }
            },
        ]
    }},

    // Keep the document and a copy of the features array
    { "$project": {
        "_id": {
            "_id": "$_id",
            "product_id": "$product_id",
            "ean": "$ean",
            "brand": "$brand",
            "model": "$model",
            "features": "$features"
        },
        "features": 1
    }},

    // Unwind the array
    { "$unwind": "$features" },

    // Find the actual elements that match the conditions
    { "$match": {
        "$or": [
            { 
               "features.key": "Screen Format",
               "features.value": "16:9"
            },
            { 
               "features.key" : "Weight in kg",
               "features.value" : { "$gt": "5", "$lt": "8" }
            },
        ]
    }},

    // Count those matched elements
    { "$group": {
        "_id": "$_id",
        "count": { "$sum": 1 }
    }},

    // Restore the document and divide the mated elements by the
    // number of elements in the "or" condition
    { "$project": {
        "_id": "$_id._id",
        "product_id": "$_id.product_id",
        "ean": "$_id.ean",
        "brand": "$_id.brand",
        "model": "$_id.model",
        "features": "$_id.features",
        "matched": { "$divide": [ "$count", 2 ] }
    }},

    // Sort by the matched percentage
    { "$sort": { "matched": -1 } }

])

Takže jak znáte "délku" $or podmínku, pak musíte jednoduše zjistit, kolik prvků v poli "features" odpovídá těmto podmínkám. Takže to je to, o čem je druhý $match v potrubí.

Jakmile získáte tento počet, jednoduše vydělíte počtem podmínek, které byly předány jako vaše $or . Krása je v tom, že nyní můžete udělat něco užitečného s tímto způsobem, jako je řazení podle relevance a poté dokonce "stránkování" na straně serveru s výsledky.

Samozřejmě, pokud chcete nějakou další "kategorizaci" tohoto, vše, co byste museli udělat, je přidat další $project etapa do konce potrubí:

    { "$project": {
        "product_id": 1
        "ean": 1
        "brand": 1
        "model": 1,
        "features": 1,
        "matched": 1,
        "category": { "$cond": [
            { "$eq": [ "$matched", 1 ] },
            "100",
            { "$cond": [ 
                { "$gte": [ "$matched", .7 ] },
                "70-99",
                { "$cond": [
                   "$gte": [ "$matched", .4 ] },
                   "40-69",
                   "under 40"
                ]} 
            ]}
        ]}
    }}

Nebo jako něco podobného. Ale $cond Zde vám může pomoci operátor.

Architektura by měla být v pořádku, jak ji máte, protože můžete mít složený index na "klíč" a "hodnota" pro položky v poli funkcí a to by se mělo dobře škálovat pro dotazy.

Samozřejmě, pokud skutečně potřebujete něco víc než to, jako je fasetové vyhledávání a výsledky, můžete se podívat na řešení jako Solr nebo elastické vyhledávání. Ale jeho úplná implementace by zde byla trochu zdlouhavá.



  1. Existuje nějaké omezení počtu argumentů, které zvládnou příkazy redis, jako je ZADD nebo HMGET?

  2. Jak vytvořím pracovníka resque automaticky při spuštění?

  3. Jednoduchá přihlašovací stránka v nodejs pomocí expresu a pasu s mongodb

  4. Jak zvýšit výkon Redis při 100% CPU? Sdílení? Nejrychlejší .Net klient?