2017-10-24 39 views
11

Powiedzmy, że mamy zbiór dokumentów jak ten:Znajdź jeśli element w tablicy ma wartość równą wartości elementu nadrzędnego

{ 
    "_id" : ObjectId("591c54faf1c1f419a830b9cf"), 
    "fingerprint" : "3121733676", 
    "screewidth" : "1920", 
    "carts" : [ 
     { 
      "cartid" : 391796, 
      "status" : "New", 
      "cart_created" : ISODate("2017-05-17T13:50:37.388Z"), 
      "closed" : false, 
      "items" : [ 
       { 
        "brandid" : "PIR", 
        "cai" : "2259700" 
       } 
      ], 
      "updatedon" : ISODate("2017-05-17T13:51:24.252Z") 
     }, 
     { 
      "cartid" : 422907, 
      "status" : "New", 
      "cart_created" : ISODate("2017-10-23T08:57:06.846Z"), 
      "closed" : false, 
      "items" : [ 
       { 
        "brandid" : "PIR", 
        "cai" : "IrHlNdGtLfBoTlKsJaRySnM195U" 
       } 
      ], 
      "updatedon" : ISODate("2017-10-23T09:46:08.579Z") 
     } 
    ], 
    "createdon" : ISODate("2016-11-08T10:29:55.120Z"), 
    "updatedon" : ISODate("2017-10-23T09:46:29.486Z") 
} 

Jak można wyodrębnić tylko te dokumenty, w których żadna pozycja w tablicy $. wózki mają $ .carts.closed set to true i $.carts.updatedon większy niż $.updatedon minus 3 dni?

wiem jak to zrobić znajdują się wszystkie dokumenty, w których żaden element w tablicy spełniają warunek $and: [closed: {$eq: true}, {updatedon: {$gt : new ISODate("2017-10-20T20:15:31Z")}}]

Ale jak można odwoływać elementu nadrzędnego $.updatedon dla porównania?

W prostym języku zapytań powłoki mongody byłoby to jednak pomocne.

Ale ja właściwie dostępu do niego za pomocą sterownika C#, więc mój filtr zapytanie jest tak:

FilterDefinition<_visitorData> filter; 
filter = Builders<_visitorData>.Filter 
    .Gte(f => f.updatedon, DateTime.Now.AddDays(-15)); 
filter = filter & (
    Builders<_visitorData>.Filter 
    .Exists(f => f.carts, false) 
     | !Builders<_visitorData>.Filter.ElemMatch(f => 
     f.carts, c => c.closed && c.updatedon > DateTime.Now.AddDays(-15) 
    ) 
); 

Jak mogę zastąpić DateTime.Now.AddDays(-15) z odniesieniem do elementu głównego dokumentu updatedon?

+0

Nie jestem pewien, czy czegoś brakuje, ale jeśli używasz 'f.updatedon' podczas porównywania' c.updatedon', to nie działa? –

+0

@VivekAthalye nope, ponieważ f nie jest dostępne po prawej stronie ElemMatch –

Odpowiedz

2

Możesz wyświetlić różnicę carts.updatedon i updatedon, a następnie odfiltrować wyniki z tego potoku agregacji.

coll.aggregate([{'$unwind':'$carts'}, 
       {'$match':{'closed':{'$ne':true}}}, 
       {'$project':{'carts.cartid':1,'carts.status':1,'carts.cart_created':1,'carts.closed':1,'carts.items':1,'carts.updatedon':1,'updatedon':1,'diff':{'$subtract':['$carts.updatedon','$createdon']}}}, 
       {'$match': {'diff': {'$gte': 1000 * 60 * 60 * 24 * days}}}]) 

dni = 3 odfiltrowuje wyniki więcej niż 3 dni dokumentów różnicowych.

Właśnie podałem przykład, w jaki sposób można użyć funkcji odejmowania $, aby znaleźć różnicę dat i filtrować dokumenty na jej podstawie.

1

Cóż, byłem w podobnej sytuacji kilka dni temu. Rozwiązałem go za pomocą Jobject z Newtonsoft.Json. Utwórz funkcję zwracania wartości bool, która faktycznie przetwarza każdy dokument, podejmij go jako dane wejściowe.

Jobject jOb=Jobject.parse(<Your document string>); 
    JArray jAr=JArray.Parse(jOb["carts"]); 
    If(jOb["updateon"]=<Your Business Validation>) 
    { 
    foreach(var item in jAr) 
     if(item["closed"]==<Your validation>){ return true}   

    } 
return false; 

Mam nadzieję, że to pomoże :) Jeśli obsługa wszelkich wartości null w tych właściwości następnie proszę posłużyć się Tryparse i zmiennej.