DocumentDB SQL - Các hàm do người dùng xác định

DocumentDB SQL cung cấp hỗ trợ cho các hàm do người dùng xác định (UDF). UDF chỉ là một loại hàm JavaScript khác mà bạn có thể viết và những hàm này hoạt động khá nhiều như bạn mong đợi. Bạn có thể tạo UDF để mở rộng ngôn ngữ truy vấn với logic nghiệp vụ tùy chỉnh mà bạn có thể tham chiếu trong các truy vấn của mình.

Cú pháp DocumentDB SQL được mở rộng để hỗ trợ logic ứng dụng tùy chỉnh bằng cách sử dụng các UDF này. UDF có thể được đăng ký với DocumentDB và sau đó được tham chiếu như một phần của truy vấn SQL.

Hãy xem xét ba tài liệu sau đây cho ví dụ này.

AndersenFamily tài liệu như sau.

{ 
   "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 tài liệu như sau.

{ 
   "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 tài liệu như sau.

{ 
   "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 
}

Hãy xem một ví dụ mà chúng ta sẽ tạo một số UDF đơn giản.

Sau đây là việc thực hiện CreateUserDefinedFunctions.

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

Chúng tôi có một udfRegEx và trong CreateUserDefinedFunction, chúng tôi lấy mã JavaScript của nó từ tệp cục bộ của chúng tôi. Chúng tôi xây dựng đối tượng định nghĩa cho UDF mới và gọi CreateUserDefinedFunctionAsync với SelfLink của bộ sưu tập và đối tượng udfDefinition như được hiển thị trong đoạn mã sau.

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; 
}

Chúng tôi lấy lại UDF mới từ thuộc tính tài nguyên của kết quả và trả lại nó cho người gọi. Để hiển thị UDF hiện có, sau đây là cách triển khaiViewUserDefinedFunctions. Chúng tôi gọiCreateUserDefinedFunctionQuery và lặp lại chúng như bình thường.

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 không cung cấp các hàm tích hợp để tìm kiếm các chuỗi con hoặc các biểu thức chính quy, do đó, một dòng chữ nhỏ sau đây sẽ lấp đầy khoảng trống đó là một hàm JavaScript.

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

Với chuỗi đầu vào trong tham số đầu tiên, hãy sử dụng hỗ trợ biểu thức chính quy có sẵn của JavaScript để chuyển chuỗi khớp mẫu trong tham số thứ hai vào.match. Chúng tôi có thể chạy một truy vấn chuỗi con để tìm tất cả các cửa hàng có từ Andersen tronglastName bất động sản.

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); 
   } 
}

Lưu ý rằng chúng ta phải đủ điều kiện cho mọi tham chiếu UDF có tiền tố udf. Chúng tôi vừa chuyển SQL tớiCreateDocumentQuerygiống như bất kỳ truy vấn thông thường nào. Cuối cùng, hãy gọi các truy vấn trên từCreateDocumentClient bài tập

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); 
   } 
}

Khi đoạn mã trên được thực thi, nó sẽ tạo ra kết quả sau.

**** 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