2015-07-07 10 views
6

Próbuję uzyskać zachowanie "getOrCreate" przy użyciu "findAndModify". Pracuję w nodejs przy użyciu natywnego sterownika.Nie można określić pól zapytania, aby ustawić błąd wstawiania

mam:

var matches = db.collection("matches"); 
matches.findAndModify({ 
     //query 
     users: { 
      $all: [ userA_id, userB_id ] 
     }, 
     lang: lang, 
     category_id: category_id 
    }, 
    [[ "_id", "asc"]], //order 
    { 
     $setOnInsert: { 
      users: [userA_id, userB_id], 
      category_id: category_id, 
      lang: lang, 
      status: 0 
     } 
    }, 
    { 
     new:true, 
     upsert:true 
    }, function(err, doc){ 
     //Do something with doc 
    }); 

Co starałem się zrobić to: „Znajdź konkretny mecz z określonych użytkowników, lang i kategorię ... jeśli nie znaleziono, włóż nową kartę z określonymi danymi”

Mongo rzuca ten błąd:

Error getting/creating match { [MongoError: exception: cannot infer query fields to set, path 'users' is matched twice] 
    name: 'MongoError', 
    message: 'exception: cannot infer query fields to set, path \'users\' is matched twice', 
    errmsg: 'exception: cannot infer query fields to set, path \'users\' is matched twice', 
    code: 54, 
    ok: 0 } 

Czy istnieje sposób, aby to działało? To niemożliwe?

Dziękuję :)

Odpowiedz

2

To nie jest „najładniejszy” sposób sobie z tym poradzić, ale obecne ograniczenia dotyczące operatorów selekcji znaczy trzeba by użyć wyrażenia z JavaScript.

podstawiając vars dla wartości dla ułatwienia przykład:

matches.findAndModify(
    { 
     "$where": function() { 
      var match = [1,2]; 
      return this.users.filter(function(el) { 
       return match.indexOf(el) != -1; 
      }).length >= 2; 
     }, 
     "lang": "en", 
     "category_id": 1 
    }, 
    [], 
    { 
     "$setOnInsert": { 
      "users": [1,2], 
      "lang": "en", 
      "category_id": 1  
     } 
    }, 
    { 
     "new": true, 
     "upsert": true 
    }, 
    function(err,doc) { 
     // do something useful here 
    } 
); 

Jak można podejrzewać, The „winowajcą” jest tutaj positional $ operator, mimo że operacja nie skorzystać z niego.

Problem polega na tym, że $all szuka możliwego dopasowania na "dwóch" pozycjach w tablicy. W przypadku, gdy operator "pozycyjny" byłby wymagany, silnik nie może wyodrębnić (obecnie) pozycji do zaprezentowania. Pozycja powinna być prawdopodobnie "pierwszym" zgodnym z innymi operacjami, ale obecnie nie działa w ten sposób.

Zastąpienie logiki wyrażeniem JavaScript powoduje obejście tego, ponieważ logika JavaScript nie może mimo wszystko zwrócić dopasowanej pozycji. To sprawia, że ​​wyrażenie jest prawidłowe, a następnie można "utworzyć" i utworzyć tablicę z dwoma elementami w nowym dokumencie lub pobrać dokument, który zawiera "oba" te elementy, jak również inne warunki zapytania.


P. Trochę martwię się o twój "rodzaj" tutaj. Być może dodałeś go, ponieważ jest "obowiązkowy" dla tej metody, jednak jeśli prawdopodobnie spodziewasz się, że to będzie pasowało do "więcej niż jednego" dokumentu i potrzebujesz "sortowania", aby ustalić, który z nich ma zostać uzyskany, wtedy twoja logika jest nieco wadliwa.

Kiedy to robisz, aby "znaleźć lub stworzyć", to naprawdę musisz potrzebujesz, aby określić "wszystkie" "kluczowe" ograniczenia klucza w zapytaniu. Jeśli tego nie zrobisz, najprawdopodobniej natkniesz się na powtarzające się błędy kluczowe w torze.

Sortowanie może w rzeczywistości być pustą tablicą, jeśli faktycznie nie trzeba "wybierać" wyniku z wielu.

Po prostu o czym należy pamiętać.

+0

Dziękuję za odpowiedź ... działa jak urok :) – Pipe

+1

czy jest inny sposób? Nie mogę odwoływać się do innych var w funkcji $ where. ReferenceError jest generowany, gdy używam dowolnego var poza funkcją. –

+0

@SooChengKoh Nie, nie ma. Ale to nie jest twoje pytanie. Więc jeśli masz inne pytanie, proszę [zapytaj.] (Http: // stackoverflow.com/questions/ask) –

Powiązane problemy