MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Procent warunków OR dopasowanych w mongodb

Cóż, twoje rozwiązanie naprawdę powinno być specyficzne dla MongoDB, w przeciwnym razie będziesz wykonywać obliczenia i możliwe dopasowanie po stronie klienta, a to nie będzie dobre dla wydajności.

Więc oczywiście to, czego naprawdę chcesz, to sposób, aby mieć to przetwarzanie po stronie serwera:

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

])

Więc jak znasz "długość" $or jest stosowany warunek, musisz po prostu dowiedzieć się, ile elementów w tablicy „features” spełnia te warunki. A więc o to chodzi w drugim $match w potoku.

Gdy już masz tę liczbę, po prostu dzielisz przez liczbę warunków, które zostały przekazane jako $or . Piękno tutaj polega na tym, że teraz możesz zrobić coś przydatnego z tym, na przykład sortować według trafności, a nawet „stronicować” stronę serwera wyników.

Oczywiście, jeśli potrzebujesz dodatkowej „kategoryzacji” tego, wszystko, co musisz zrobić, to dodać kolejny $project etap do końca potoku:

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

Lub jako coś podobnego. Ale $cond operator może ci tutaj pomóc.

Architektura powinna być w porządku, ponieważ możesz mieć złożony indeks na „kluczu” i „wartości” dla wpisów w tablicy funkcji, a to powinno być dobrze skalowane dla zapytań.

Oczywiście jeśli faktycznie potrzebujesz czegoś więcej, np. wyszukiwania aspektowego i wyników, możesz przyjrzeć się rozwiązaniom takim jak Solr lub Elastic search. Ale pełna implementacja tego byłaby tutaj trochę długa.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Metoda wyszukiwania Mongoose z $lub warunkiem nie działa poprawnie

  2. MongoDB Ostrzeżenie o wycofaniu mangusty

  3. jak przekonwertować ciąg na wartości liczbowe w mongodb

  4. Jak wykonać zapytanie tablicowe identyfikatorów w Mongoose?

  5. mongodb jak zmienić domyślny port