Как искать на БД Космос в комплексе JSON Объект - PullRequest
2 голосов
/ 08 января 2020

У меня есть следующий JSON Объект, как вы можете видеть, он ссылается на объект TAG, который представляет собой массив тегов.

public class GlobalPageTemplate : ISharedCosmosEntity
{
    [JsonProperty("Id")]
    public string Id { get; set; }

    [CosmosPartitionKey]
    public string CosmosEntityName { get; set; }

    public string Description { get; set; }
    public string ExtractedPageName { get; set; }
    public string ExtractedSitecollectionTemplateName { get; set; }
    public string ExtractedGlobalDesignTenantId { get; set; }
    public string ExtractedGlobalDesigntenantSiteCollectionUrl { get; set; }
    public string PageTemplatePictureUrl { get; set; }
    public string Base64Image { get; set; }
    public string PageTemplateName { get; set; }
    public List<Section> Sections { get; set; }
    public string TemplateAccessLevel { get; set; }
    public List<Tag> Tags { get; set; }
}

public class Tag : ISharedCosmosEntity
{

    [JsonProperty("Id")]
    public string Id { get; set; }

    public string TagName { get; set; }

    [CosmosPartitionKey]
    public string CosmosEntityName { get; set; }
}

В базе данных объекты сохраняются следующим образом:

{
    "CosmosEntityName": "globalpagetemplates",
    "Description": "depper",
    "ExtractedPageName": "Home.aspx",
    "ExtractedSitecollectionTemplateName": "CommunicationSite",
    "ExtractedGlobalDesignTenantId": "696da7e7-a03e-4996-bbf8-625b8e4c4c06",
    "ExtractedGlobalDesigntenantSiteCollectionUrl": "https://xx.sharepoint.com/sites/TST1",
    "PageTemplatePictureUrl": "https://xx.blob.core.windows.net/globalpagetemplatespictures/0befc979-3958-4e27-a345-f4ce491eb1ee.png",
    "Base64Image": "",
    "PageTemplateName": "Plantilla 5 TST 1",
    "Sections": [],
    "TemplateAccessLevel": "Platinum",
    "Tags": [
        {
            "Id": null,
            "TagName": "recursos humanos",
            "CosmosEntityName": null
        }
    ],
    "id": "0befc979-3958-4e27-a345-f4ce491eb1ee",
    "_rid": "q6JzALvx8ZHMCQAAAAAAAA==",
    "_self": "dbs/q6JzAA==/colls/q6JzALvx8ZE=/docs/q6JzALvx8ZHMCQAAAAAAAA==/",
    "_etag": "\"35001a26-0000-0300-0000-5df77cf60000\"",
    "_attachments": "attachments/",
    "_ts": 1576500470
}

У меня есть метод, который возвращает ВСЕ шаблоны страниц:

/// <returns></returns>
[HttpGet]
public async Task<IHttpActionResult> GetGlobalPageTemplates()
{ 
    var telemetry = new TelemetryClient();
    try
    {
        var globalPageTemplateStore = CosmosStoreHolder.Instance.CosmosStoreGlobalPageTemplate;
        var globalPageTemplates =  await globalPageTemplateStore.Query().ToListAsync();
        return Ok(globalPageTemplates);
    }
    catch (Exception ex)
    {
        string guid = Guid.NewGuid().ToString();
        var dt = new Dictionary<string, string>
        {
            { "Error Lulo: ", guid }
        };

        telemetry.TrackException(ex, dt);
        return BadRequest("Error Lulo: " + guid);
    }
}

Однако в интерфейсе я могу фильтровать по TAGS,

Так что мне нужно создать метод который получает список строк, а затем делает запрос, чтобы получить шаблоны страниц, соответствующие тегам, фильтр должен быть эксклюзивным, я имею в виду ИЛИ.

/// <returns></returns>
[HttpGet]
public async Task<IHttpActionResult> GetGlobalPageTemplatesByTags(List<string> tags)
{ 
    var telemetry = new TelemetryClient();
    try
    {
        var globalPageTemplateStore = CosmosStoreHolder.Instance.CosmosStoreGlobalPageTemplate;
        var globalPageTemplates =  await globalPageTemplateStore.Query().Where???
    }
    catch (Exception ex)
    {
        string guid = Guid.NewGuid().ToString();
        var dt = new Dictionary<string, string>
        {
            { "Error Lulo: ", guid }
        };

        telemetry.TrackException(ex, dt);
        return BadRequest("Error Lulo: " + guid);
    }
}

есть идеи, как этого добиться?

Ответы [ 2 ]

1 голос
/ 08 января 2020

Вы можете попробовать этот запрос, используя Where(), Any() и Contains() из LINQ:

var globalPageTemplates = await globalPageTemplateStore
    .Query()
    .Where(template => template
        .Tags
        .Any(tag => tags.Contains(tag.TagName))
     )
     .ToListAsync();

Если вам нужен более быстрый O (1) поиск для tags, я предлагаю заранее преобразовать его в HashSet<string>:

var tagLookups = new HashSet<string>(tags);

var globalPageTemplates = await globalPageTemplateStore
    .Query()
    .Where(template => template
        .Tags
        .Any(tag => tagLookups.Contains(tag.TagName))
    )
    .ToListAsync();

Основная идея c - сначала отфильтровать каждый шаблон с Where(), затем проверьте, существует ли Any() тегов шаблонов в tags, используя Contains().

Примечание: Вы должны добавить ToListAsync() в конец запроса, чтобы преобразовать IQueryable<GlobalPageTemplate> в List<GlobalPageTemplate>. Это потому, что запрос асинхронный.

0 голосов
/ 08 января 2020

Полагаю, вы ищете решение для фильтрации GlobalPageTemplate в соответствии с TagName в List<string> tags; если да, вы можете использовать .Where с .Any и .Contains из List

Пример кода

var globalPageTemplateStore = CosmosStoreHolder.Instance.CosmosStoreGlobalPageTemplate;
var globalPageTemplates =  await globalPageTemplateStore.Query()
    .Where(.Where(c => c.Addresses.Any(a => cityList.Contains(a.City)))
    .ToList();

Примечание: Это будет работать только для Оценка клиента , и вам может потребоваться использовать .AsEnumerable

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...