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

Wstaw, jeśli nie istnieje, w przeciwnym razie usuń MongoDB

To nie jest dobry sposób na zaimplementowanie głosów za i przeciw. Poza strukturą agregacji, która w żaden sposób nie jest mechanizmem aktualizacji dokumentów, wydaje się, że skłaniasz się ku myśleniu, że może to być rozwiązanie ze względu na logikę, którą chcesz wdrożyć. Ale agregat nie aktualizuje się.

To, czego chcesz od swojego, nazwijmy to schematem „pytań”, to taka struktura:

{
    "_id": ObjectId("53f51a844ffa9b02cf01c074"),
    "upvoted": [],
    "downvoted": [],
    "upvoteCount": 0,
    "downvoteCount": 0
}

To jest coś, co może dobrze działać z niepodzielnymi aktualizacjami i jednocześnie zapewniać pewne stanowe informacje o obiekcie.

W przypadku tablic „upvoted” i „downvoted” rozważymy, że głosowanie „users” ma podobną unikatową wartość ObjectId. Zamierzamy więc zrobić $push lub $pull z dowolnej tablicy, a także "zwiększ/zmniejsz" wartości licznika wraz z każdą z tych operacji.

Oto, jak to działa w przypadku głosowania za:

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "upvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
        "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075")
    },
    {         
        "$push": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": 1, "downvoteCount": -1 },
        "$pull": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
    }
)

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "upvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
    },
    {
        "$push": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": 1 },
    }
)

Właściwie są to dwie operacje, które można wykonać za pomocą AP operacji zbiorczych Ja też (chyba najlepszy sposób naprawdę), ale ma to swój sens. Pierwsza instrukcja będzie pasować tylko do dokumentu, w którym bieżący użytkownik ma zapisany w tablicy „downvote”. W związku z tym już „przesunęliśmy” tę wartość identyfikatora użytkownika do tablicy „downvotes”. Jeśli go tam nie ma, aktualizacja nie jest wykonywana. Ale zarówno wypychasz, jak i wyciągasz z odpowiednich tablic, a także jednocześnie "zwiększasz/zmniejszasz" pola liczników.

Z drugim stwierdzeniem, które będzie pasować tylko do czegoś, co nie pasuje do pierwszego, uczciwie oceniasz, że teraz nie musisz dotykać „downvotes” i po prostu obsługiwać pola upvote. W obu przypadkach bezpieczną rzeczą do zrobienia jest upewnienie się, że głównym warunkiem jest to, że wartość bieżącego identyfikatora użytkownika nie jest obecna w tablicy „upvoted”.

W przypadku głosów przeciw, pola są po prostu odwrócone:

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "downvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
        "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075")
    },
    {         
        "$pull": { "upvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "upvoteCount": -1, "downvoteCount": 1 },
        "$push": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
    }
)

db.questions.update(
    { 
        "_id": ObjectId("53f51a844ffa9b02cf01c074"),
        "downvoted": { "$ne": ObjectId("53f51c0a4ffa9b02cf01c075") }
    },
    {
        "$push": { "downvoted": ObjectId("53f51c0a4ffa9b02cf01c075") },
        "$inc": { "downvoteCount": 1 },
    }
)

Oczywiście możesz zobaczyć logiczny postęp, aby po prostu anulować wszelkie „głosy za/w dół” dla danego użytkownika. Możesz też być mądry, jeśli chcesz i ujawnić informacje w swoim kliencie, aby nie tylko pokazać, czy bieżący użytkownik już „zagłosował/odrzucił”, ale także kontrolować działania kliknięć i eliminować niepotrzebne żądania.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Czy do identyfikacji użytkownika powinienem używać identyfikatora ObjectID lub uid (zaimplementowanego przeze mnie)?

  2. Jak usunąć duplikaty z określonym warunkiem w mongodb?

  3. Parametr include_type_name jest ustawiony na true w node.js

  4. Spring Mongo Populator jeden po drugim

  5. MongoDB:jak znaleźć dokumenty ignorujące wielkość liter, akcenty i procent jak logikę (%)