DocumentDB SQL - Benutzerdefinierte Funktionen

DocumentDB SQL bietet Unterstützung für benutzerdefinierte Funktionen (User Defined Functions, UDFs). UDFs sind nur eine andere Art von JavaScript-Funktionen, die Sie schreiben können, und diese funktionieren so ziemlich wie erwartet. Sie können UDFs erstellen, um die Abfragesprache mit benutzerdefinierter Geschäftslogik zu erweitern, auf die Sie in Ihren Abfragen verweisen können.

Die DocumentDB-SQL-Syntax wird erweitert, um benutzerdefinierte Anwendungslogik mit diesen UDFs zu unterstützen. UDFs können bei DocumentDB registriert und dann als Teil einer SQL-Abfrage referenziert werden.

Betrachten wir die folgenden drei Dokumente für dieses Beispiel.

AndersenFamily Dokument ist wie folgt.

{ 
   "id": "AndersenFamily", 
   "lastName": "Andersen", 
	
   "parents": [ 
      { "firstName": "Thomas", "relationship":  "father" }, 
      { "firstName": "Mary Kay", "relationship":  "mother" } 
   ],
   
   "children": [ 
      { 
         "firstName": "Henriette Thaulow", 
         "gender": "female", 
         "grade": 5, 
         "pets": [ { "givenName": "Fluffy", "type":  "Rabbit" } ] 
      } 
   ],
   
   "location": { "state": "WA", "county": "King", "city": "Seattle" }, 
   "isRegistered": true 
}

SmithFamily Dokument ist wie folgt.

{ 
   "id": "SmithFamily", 
	
   "parents": [ 
      { "familyName": "Smith", "givenName": "James" }, 
      { "familyName": "Curtis", "givenName": "Helen" }
   ], 
	
   "children": [ 
      { 
         "givenName": "Michelle", 
         "gender": "female", 
         "grade": 1 
      }, 
		
      { 
         "givenName": "John", 
         "gender": "male", 
         "grade": 7,
			
         "pets": [ 
            { "givenName": "Tweetie", "type": "Bird" } 
         ] 
      }
   ],
   
   "location": { 
      "state": "NY", 
      "county": "Queens", 
      "city": "Forest Hills" 
   },
   
   "isRegistered": true 
}

WakefieldFamily Dokument ist wie folgt.

{ 
   "id": "WakefieldFamily", 
	
   "parents": [ 
      { "familyName": "Wakefield", "givenName": "Robin" }, 
      { "familyName": "Miller", "givenName": "Ben" } 
   ],
   
   "children": [ 
      { 
         "familyName": "Merriam", 
         "givenName": "Jesse", 
         "gender": "female", 
         "grade": 6,
			
         "pets": [
            { "givenName": "Charlie Brown", "type": "Dog" }, 
            { "givenName": "Tiger", "type": "Cat" }, 
            { "givenName": "Princess", "type": "Cat" } 
         ] 
      },
		
      { 
         "familyName": "Miller", 
         "givenName": "Lisa", 
         "gender": "female", 
         "grade": 3,
			
         "pets": [ 
            { "givenName": "Jake", "type": "Snake" } 
         ] 
      } 
   ],
   
   "location": { "state": "NY", "county": "Manhattan", "city": "NY" }, 
   "isRegistered": false 
}

Schauen wir uns ein Beispiel an, in dem wir einige einfache UDFs erstellen.

Es folgt die Implementierung von CreateUserDefinedFunctions.

private async static Task CreateUserDefinedFunctions(DocumentClient client) { 
   Console.WriteLine(); 
   Console.WriteLine("**** Create User Defined Functions ****"); 
   Console.WriteLine();  
	
   await CreateUserDefinedFunction(client, "udfRegEx");  
}

Wir haben eine udfRegEx und in CreateUserDefinedFunction erhalten wir den JavaScript-Code aus unserer lokalen Datei. Wir erstellen das Definitionsobjekt für die neue UDF und rufen CreateUserDefinedFunctionAsync mit dem SelfLink der Sammlung und dem udfDefinition-Objekt auf, wie im folgenden Code gezeigt.

private async static Task<UserDefinedFunction>
CreateUserDefinedFunction(DocumentClient client, string udfId) { 
   var udfBody = File.ReadAllText(@"..\..\Server\" + udfId + ".js"); 
	
   var udfDefinition = new UserDefinedFunction { 
      Id = udfId, 
      Body = udfBody 
   }; 
   
   var result = await client
      .CreateUserDefinedFunctionAsync(_collection.SelfLink, udfDefinition); 
   var udf = result.Resource; 
	
   Console.WriteLine("Created user defined function {0}; RID: {1}", 
      udf.Id, udf.ResourceId);  
		
   return udf; 
}

Wir erhalten die neue UDF von der Ressourceneigenschaft des Ergebnisses zurück und geben sie an den Aufrufer zurück. Um die vorhandene UDF anzuzeigen, folgt die Implementierung vonViewUserDefinedFunctions. Wir nennenCreateUserDefinedFunctionQuery und durchlaufen sie wie gewohnt.

private static void ViewUserDefinedFunctions(DocumentClient client) { 
   Console.WriteLine(); 
   Console.WriteLine("**** View UDFs ****"); 
   Console.WriteLine(); 
	
   var udfs = client  
      .CreateUserDefinedFunctionQuery(_collection.UserDefinedFunctionsLink) 
      .ToList();  
		
   foreach (var udf in udfs) { 
      Console.WriteLine("User defined function {0}; RID: {1}", udf.Id, udf.ResourceId); 
   }
}

DocumentDB SQL bietet keine integrierten Funktionen zum Suchen nach Teilzeichenfolgen oder regulären Ausdrücken. Daher füllt der folgende kleine Einzeiler diese Lücke, die eine JavaScript-Funktion ist.

function udfRegEx(input, regex) { 
   return input.match(regex); 
}

Verwenden Sie für die Eingabezeichenfolge im ersten Parameter die in JavaScript integrierte Unterstützung für reguläre Ausdrücke, indem Sie die Mustervergleichszeichenfolge im zweiten Parameter an übergeben.match. Wir können eine Teilstring-Abfrage ausführen, um alle Geschäfte mit dem Wort Andersen zu findenlastName Eigentum.

private static void Execute_udfRegEx(DocumentClient client) { 
   var sql = "SELECT c.name FROM c WHERE udf.udfRegEx(c.lastName, 'Andersen') != null";
	
   Console.WriteLine(); 
   Console.WriteLine("Querying for Andersen"); 
	
   var documents = client.CreateDocumentQuery(_collection.SelfLink, sql).ToList();  
   Console.WriteLine("Found {0} Andersen:", documents.Count); 
	
   foreach (var document in documents) { 
      Console.WriteLine("Id: {0}, Name: {1}", document.id, document.lastName); 
   } 
}

Beachten Sie, dass wir jede UDF-Referenz mit dem Präfix qualifizieren müssen udf. Wir haben gerade die SQL an weitergegebenCreateDocumentQuerywie jede gewöhnliche Abfrage. Rufen wir abschließend die obigen Abfragen aus dem aufCreateDocumentClient Aufgabe

private static async Task CreateDocumentClient() { 
   // Create a new instance of the DocumentClient 
	
   using (var client = new DocumentClient(new Uri(EndpointUrl), AuthorizationKey)){ 
      database = client.CreateDatabaseQuery("SELECT * FROM c WHERE 
         c.id = 'myfirstdb'").AsEnumerable().First();
      collection = client.CreateDocumentCollectionQuery(database.CollectionsLink, 
         "SELECT * FROM c WHERE c.id = 'Families'").AsEnumerable().First();
			 
      await CreateUserDefinedFunctions(client);
   
      ViewUserDefinedFunctions(client);
   
      Execute_udfRegEx(client); 
   } 
}

Wenn der obige Code ausgeführt wird, wird die folgende Ausgabe erzeugt.

**** Create User Defined Functions ****  
Created user defined function udfRegEx; RID: kV5oANVXnwAlAAAAAAAAYA==  
**** View UDFs ****  
User defined function udfRegEx; RID: kV5oANVXnwAlAAAAAAAAYA==  
Querying for Andersen 
Found 1 Andersen: 
 Id: AndersenFamily, Name: Andersen