sql >> Database >  >> NoSQL >> MongoDB

Percentage OK-condities overeenkomend in mongodb

Welnu, uw oplossing zou echt MongoDB-specifiek moeten zijn, anders zult u uw berekeningen en mogelijke overeenkomsten aan de kant van de klant doen, en dat is niet goed voor de prestaties.

Dus wat je natuurlijk echt wilt, is een manier om die verwerking aan de serverkant te hebben:

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 } }

])

Dus zoals u de "lengte" kent van de $or voorwaarde wordt toegepast, hoeft u alleen maar uit te zoeken hoeveel van de elementen in de array "features" aan die voorwaarden voldoen. Dus dat is waar de tweede $match in de pijplijn over gaat.

Zodra je dat aantal hebt, deel je gewoon door het aantal voorwaarden wat is doorgegeven als je $or . Het mooie hiervan is dat je nu iets nuttigs hiermee kunt doen, zoals sorteren op die relevantie en dan zelfs de resultatenserverkant 'pagina'.

Natuurlijk, als je wat extra "categorisatie" hiervan wilt, hoef je alleen maar een ander $project toe te voegen stap naar het einde van de pijplijn:

    { "$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"
                ]} 
            ]}
        ]}
    }}

Of als iets soortgelijks. Maar de $cond operator kan je hier helpen.

De architectuur zou in orde moeten zijn zoals je die hebt, want je kunt een samengestelde index hebben op de "sleutel" en "waarde" voor de items in je feature-array en dit zou goed moeten schalen voor query's.

Als je echt iets meer nodig hebt dan dat, zoals facetzoeken en resultaten, kun je natuurlijk kijken naar oplossingen als Solr of elastisch zoeken. Maar de volledige implementatie daarvan zou hier wat lang duren.



  1. MongoDB-jokerteken in de sleutel van een query

  2. 'Veld had een boon nodig van het type dat niet gevonden kon worden.' fout lente rustgevende API met behulp van mongodb

  3. hoe te groeperen in mongoDB en alle velden in resultaat te retourneren

  4. Hoe voeg ik HTML in Mongodb in?