2017-11-17 21 views
0

Ich arbeite mit Couchbase v4.5 und der .NET SDK Version 2.3.8. Ich bin dabei, eine Sicht auf eine N1QL-Abfrage zu migrieren. Die Javascripts, die für die Ansicht verfügbar sind, haben mir die Flexibilität geboten, Array-Elemente des Dokuments zu sortieren und anschließend nur ein einzelnes Element aus dem Array auszuwählen. Während also in meiner Sicht hatte ich:Auswählen eines bestimmten Array-Elements

'Username': doc.Document.LogActions.sort(function(a,b){ return (a.Time > b.Time) })[doc.Document.LogActions.length - 1].Username 

... Ich kämpfe jetzt das gleiche über den .NET-SDK in einer N1QL Abfrage zu erreichen. Der Vorbehalt ist, dass ich versuche, dies nur in LINQ zu tun. Ich weiß, dass ich die Raw-String-Abfragen verwenden kann, die volle N1QL-Unterstützung bieten, aber der Teamleiter möchte dies über LINQ tun ... es sei denn, es gibt absolut keine Möglichkeit, dies über LINQ zu tun.

Ich habe versucht, die folgenden:

Sortierung - Nicht von einem Grundstück auf ein Objekt in einem Array

Username = doc.Document.LogActions 
         .OrderByDescending(logAction => logAction.Time) 
         .FirstOrDefault() 
         .Username, 

Nehmen Sie einfach Last zu sortieren erlaubt - nicht

unterstützt Letzte

Keine Sortierung - Stil l gibt ein Array

Username = transaction.Document 
         .LogActions[transaction.Document.LogActions.Count - 1] 
         .Username 

Das einzige, was ich denken kann, zu tun, ist nur das Array wieder zurück zu .NET und führen Sie die dort Filterung. Wir haben jedoch keine Basis für wie viele Elemente im Array im Durchschnitt sein werden. Wir würden lieber vermeiden, Daten zurück zu holen, die wir nicht brauchen.

Bin ich auf die Verwendung einer Raw-String-Abfrage verwiesen? Idealerweise versuche ich, ausgehend von der Eigenschaft Time, die letzte "Protokollaktion" aus dem Array zu finden.

Antwort

1

spielte ich um einiges mehr mit diesem, und während es wie so etwas scheint funktionieren sollte:

Username = transaction.Document.LogActions 
           .OrderByDescending(logAction => logAction.Time) 
           .Select(g => g.Username) 
           .ToArray()[0], 

... ach, es funktioniert nicht. Ich erhalte einen Fehler von "N1Ql-Array-Unterabfragen unterstützen nur eine Bestellung durch die Array-Elemente". Also habe ich versucht, einen GroupBy mit --Für kichert - und siehe da ich Ergebnisse tun zurück:

Username = transaction.Document.LogActions 
           .OrderByDescending(logAction => logAction.Time) 
           .GroupBy(logAction => new { logAction.Time, logAction.Username }) 
           .Select(g => g.Key.Username) 
           .ToArray()[0], 

Dies lässt mich mit der Bestätigung, dass ich die richtige Ergebnis zurück - da CB Bestellung ein scheint bisschen wackelig - aber es ist zumindest halb funktionierend.

0

Ich bin kein Experte für LINQ. Aber das Folgende ist N1QL Abfrage.

MAX, MIN Argument erlaubt Array. Das 0. Element des Arrays kann Feldbedarfsaggregat sein und das erste Element ist das, was Sie tragen möchten. Mit dieser Technik können Sie nicht aggregiertes Feld für MIN/MAX wie unten dargestellt projizieren.

INSERT INTO default VALUES ("k01",{ "logActions":[ { "User":"u1", "Time":"2017-11-52T14:35:00Z" }, { "User":"u2", "Time":"2017-11-09T14:35:00Z" }, { "User":"u3", "Time":"2017-11-03T14:35:00Z" }, { "User":"u4", "Time":"2017-11-02T14:35:00Z" }, ] }); 
SELECT MAX([u.Time,u.User])[1] AS User FROM default d USE KEYS "k01" UNNEST d.logActions AS a; 

Kasse Auch N1QL : Find latest status from an array

In 5.0.0 N1QL Unterabfrage Ausdruck verwendet, kann diese https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-language-reference/subqueries.html erreicht werden.

Verwandte Themen