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

Dynamiczne lepkie sortowanie w Mongo dla prostej wartości lub listy

Nie można odtworzyć Twojego błędu, ale w Twoim pytaniu jest kilka literówek, więc nie mogę być pewien, co tak naprawdę masz.

Ale zakładając, że faktycznie pracujesz z MongoDB w wersji 2.6 lub nowszej, prawdopodobnie potrzebujesz $setIntersection lub $setIsSubset operatorów zamiast $setUnion . Operatory te oznaczają „dopasowanie” zawartości tablicy, z którą są porównywane, gdzie $setUnion po prostu łączy dostarczoną tablicę z istniejącą:

db.people.aggregate([
    { "$project": {
        "first_name": 1,
        "last_name": 1,
        "sticky": { 
            "$size": { 
                "$setIntersection": [ "$offices", [ "FL", "SC" ]] 
            }
        },
        "offices": 1
    }},
    { "$sort": {
        "sticky": -1,
        "last_name": 1
    }}
])

W poprzednich wersjach, w których nie ma tych operatorów zestawów po prostu używasz $unwind do pracy z tablicą i tego samego rodzaju $cond operacja jak poprzednio w $group aby to wszystko połączyć:

db.people.aggregate([
    { "$unwind": "$offices" },
    { "$group": {
        "_id": "$_id",
        "first_name": { "$first": "$first_name" },
        "last_name": { "$first": "$last_name",
        "sticky": { "$sum": { "$cond": [
            { "$or": [
                { "$eq": [ "$offices": "FL" ] },
                { "$eq": [ "$offices": "SC" ] },
            ]},
            1,
            0
        ]}},
        "offices": { "$push": "$offices" }
    }},
    { "$sort": {
        "sticky": -1,
        "last_name": 1
    }}
])

Ale z pewnością byłeś na dobrej drodze. Po prostu wybierz odpowiednią operację zestawu lub inną metodę, aby uzyskać dokładne potrzeby.

Lub ponieważ opublikowałeś swój sposób na zdobycie tego, czego chcesz, lepszym sposobem na napisanie tego rodzaju „uporządkowanego dopasowania” jest:

db.people.aggregate([
    { "$project": {
        "first_name": 1,
        "last_name": 1,
        "sticky": { "$cond": [
            { "$anyElementTrue": {
                "$map": {
                    "input": "$offices",
                    "as": "o",
                    "in": { "$eq": [ "$$o", "FL" ] }
                }
            }},
            2,
            { "$cond": [
                { "$anyElementTrue": {
                    "$map": {
                        "input": "$offices",
                        "as": "o",
                        "in": { "$eq": [ "$$o", "SC" ] }
                    }
                }},
                1,
                0
            ]}
        ]},
        "offices": 1
    }},
    { "$sort": {
        "sticky": -1,
        "last_name": 1
    }}
])

A to dałoby pierwszeństwo dokumentom z „urzędami” zawierającymi „FL” nad „SC”, a więc nad wszystkimi innymi, i wykonywaniu operacji w obrębie jednego pola. Powinno to być również bardzo łatwe dla ludzi, aby zobaczyć, jak abstrahować to do formularza za pomocą $unwind we wcześniejszych wersjach bez operatorów zestawu. Gdzie po prostu podajesz wyższą wartość „wagi” elementom, które chcesz umieścić na górze, zagnieżdżając $cond oświadczenia.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Zidentyfikuj ostatni dokument z zestawu wyników wyszukiwania MongoDB find()

  2. Wstaw słownik do MongoDB za pomocą sterownika c#

  3. MongoDB 4.0 JRException:Wymagana jest opcja „kursor”, z wyjątkiem agregacji z argumentem wyjaśniania

  4. elegancka lista powtarzających się podpunktów

  5. Mongodb upsert rzuca wyjątek DuplicateKeyException