CRUD operations with Entities in DialogFlow (C #)

Introduction


Most recently, I began work on a new project, which included working with Google’s already well-known service (AI) - DialogFlow. The bottom line was that we had a bot (Telegram) that worked with the API of several sites, while DialogFlow itself helped us to structure the communication with a person, for which he basically was created. I must say that the article is intended for people who have just started acquaintance with the service or already have little experience, so the following terms are possible: Intent, Context, Action, Event and for what we gathered for the sake of - Entities. I hope that the article will be useful to those who did not understand a little how exactly through the code CRUD operations with Entities can be done.

Entities in DialogFlow


In DialogFlow Entities are some entities that consist of ReferenceValue and Synonyms. Something similar to a key-value, only with the difference that there can be a lot of synonyms, and the more there are, the better, because it “simplifies the bot’s life” and it’s easier for him to understand what value is being talked about, and the checkmark Fuzzy matching will help the bot also understand what is at stake, even if you miss one letter or another symbol. It looks something like this:

Moscow - Moscow, Moscow, Moscow ...

Finishing a short excursion, I would like to add that it is with Entity that there is a lot of fuss. Of course, I do not reduce the meaning of intents, and so on, but the fact remains.

EntityTypes


Here was the first, albeit small, pitfall for me. After all, the documentation has methods for working with Entity, and there are methods for working with EntityType - which of them is what?

In fact, everything is not so complicated, just the confusion arises due to the fact that in DialogFlow itself the tab with EntityTypes is called Entities:

image

EntityType: image

Entitie: image

Although it is believed in DialogFlow itself that there is Entity and it has Entries (i.e. The essence and entries in it).

Let's move on.

You can create an EntityType manually directly on DialoFlow, but I will show how this can be done through the code (after all, in order to create Entities we will need to know in which EntityType it should be done).

First, enable the NuGet package Google.Cloud.Dialogflow.V2. At the time of writing, version 1.1.0 was installed:

image

First we create a class and call it EntityTypeManagement in which there will be basic operations:

using Google.Api.Gax;
using Google.Cloud.Dialogflow.V2;

public class EntityTypeManagement
    {
      //Create -   EntityType   Test1 (  ) 
      //projectId - Id    DialogFlow
      //displayName -         
        public async Task Create(string projectId, string displayName, EntityType.Types.Kind kind = 
      EntityType.Types.Kind.Map)
        {
            var client = await EntityTypesClient.CreateAsync();

            var entityType = new EntityType();
            entityType.DisplayName = displayName;
            entityType.Kind = kind;

            var createdEntityType = client.CreateEntityType(
                parent: new ProjectAgentName(projectId),
                entityType: entityType
            );

            Console.WriteLine($"Created EntityType: {createdEntityType.Name}");
        }
       
      //List -   EntityTypes   
      //projectId - Id    DialogFlow
        public async Task<PagedEnumerable<ListEntityTypesResponse,EntityType>> List(string projectId)
        {
            var client = await EntityTypesClient.CreateAsync();
            var response = client.ListEntityTypes(
                parent: new ProjectAgentName(projectId)
            );
            return response;
        }

       //GetEntityTypeId -  EntityType  
       //projectId - Id    DialogFlow
       //targetEventTypeName -  EntityType,    
        public async Task<string> GetEntityTypeId(string projectId,string targetEventTypeName)
        {
            var client = await EntityTypesClient.CreateAsync();
            var response = client.ListEntityTypes(
                parent: new ProjectAgentName(projectId)
            );
            string id = response.Where(x => x.DisplayName == targetEventTypeName).FirstOrDefault().Name;
            string returningId = id.Replace($"projects/{projectId}/agent/entityTypes/", "");
            return returningId;
        }

       //Delete  BatchDelete      EntityType
       //   entityTypeId
        public async Task Delete(string projectId, string entityTypeId)
        {
            var client = await EntityTypesClient.CreateAsync();

            client.DeleteEntityType(new EntityTypeName(projectId, entityTypeId: entityTypeId));

            Console.WriteLine($"Deleted EntityType: {entityTypeId}");

        }

        
        public async Task BatchDelete(string projectId, IEnumerable<string> entityTypeIds)
        {
            var client = await EntityTypesClient.CreateAsync();
            var entityTypeNames = entityTypeIds.Select(
                id => new EntityTypeName(projectId, id).ToString());
            client.BatchDeleteEntityTypes(new ProjectAgentName(projectId),
                entityTypeNames);
        }
    }

Here it must be said right away that there is no Update function only because Create already performs its function.

Now that we have the basic methods for working with EntityTypes, let's move on to Entity and immediately create an EntityManagement class:

public class EntityManagement
    {
       using Google.Cloud.Dialogflow.V2;        


      //Create -    Entity
      //entityTypeId - Id EntityType      Entity
      //entityValue - ReferenceValue  Entity
      // synonyms -    Entity
        public async Task Create(string projectId,
                                 string entityTypeId,
                                 string entityValue,
                                 string[] synonyms)
        {
            var client = await EntityTypesClient.CreateAsync();
            var entity = new EntityType.Types.Entity() { Value = entityValue};
            entity.Synonyms.AddRange(synonyms);
            
            var operation = await client.BatchCreateEntitiesAsync(
                parent: new EntityTypeName(projectId, entityTypeId),
                entities: new[] { entity }
            ); 
            operation.PollUntilCompleted();
        }

       //CreateMany -   Entities 
       //entityTypeId - Id EntityType      Entity
       //entities -  Entities  
        public async Task CreateMany(string projectId,string entityTypeId, IEnumerable<Entity> entities)
        {
            var client = await EntityTypesClient.CreateAsync();
            List<EntityType.Types.Entity> results = new List<EntityType.Types.Entity>();
            foreach (var item in entities)
            {
                var entity = new EntityType.Types.Entity() { Value = item.value };
                entity.Synonyms.AddRange(item.synonyms);
                results.Add(entity);
            }
           
            var operation = await client.BatchCreateEntitiesAsync(
                parent: new EntityTypeName(projectId, entityTypeId),
                entities: results.ToArray());
            operation.PollUntilCompleted();
        }

      //Delete -    Entity,   "string entityValue"   
     //string[] entityValue      entityValues: entityValue
     //    .
        public async Task Delete(string projectId, string entityTypeId, string entityValue)
        {
            var client = await EntityTypesClient.CreateAsync();

            var operation = await client.BatchDeleteEntitiesAsync(
                parent: new EntityTypeName(projectId, entityTypeId),
                entityValues: new[] { entityValue }
            );

            Console.WriteLine("Waiting for the entity deletion operation to complete.");
            operation.PollUntilCompleted();

            Console.WriteLine($"Deleted Entity: {entityValue}");

        }
        
      //List -   Entities  EntityType 
     public async Task<List<Entity>> List(string projectId, string entityTypeId)
        {
            var client = await EntityTypesClient.CreateAsync();
            var entityType = await client.GetEntityTypeAsync(new EntityTypeName(
                projectId, entityTypeId
            ));
            List<Entity> EntitiesList = new List<Entity>();
            
            foreach (var entity in entityType.Entities)
            {
                List<string> Synonyms = new List<string>();
                foreach (var item in entity.Synonyms)
                {
                    Synonyms.Add(item);
                }
                EntitiesList.Add(new Entity { value = entity.Value, synonyms = Synonyms.ToArray() });
                Synonyms = null;
            }

            return EntitiesList;
        }
    }

Add our model that will represent Entity:

public class Entity
    {
        public string value { get; set; }
        public string[] synonyms { get; set; }
    }

Done, all basic CRUD features are ready. Again, returning to Update, it can be implemented separately, but it is simply not needed, since Create works like Update too.

The examples are quite simple and, I must agree, there is still a "hardcode", but I hope the article is useful to those who, like me, could not figure out how to correctly perform CRUD operations through code.

static void Main(string[] args)
        {
      EntityTypesManagement entityTypesManagement = new EntityTypesManagement();
      EntityManagement entityManagement = new EntityManagement();
       string ProjectId = "Your Project`s id";
       string EntityName = "Your EntityName";
      var entityId = await entityTypesManagement.GetEntityTypeId(ProjectId, EntityName);
       Entity entity =  new Entity{value = "1", synonyms = new[]{"1","1"}};
      /*await*/ entityManagement.Create(ProjectId,entityId,entity);
 }

Source: https://habr.com/ru/post/undefined/


All Articles