Запросите JSON в CosmosDB, чтобы найти строки, которые нарушают ограничение varchar - PullRequest
0 голосов
/ 04 июня 2019

Несколько дней назад я столкнулся с проблемой, которая была абсолютно моей, и теперь мне нужна помощь в исправлении некоторых данных.

У меня есть несколько документов JSON, хранящихся в CosmosDB, и у меня есть приложение-функция для преобразования этих документов JSON в таблицу SQL Azure.Ошибка, с которой я столкнулся, состояла в том, что я поместил один из столбцов как varchar 200, и ошибка была вызвана строками в этом JSON, которые превышают этот предел символов.Немного упущения, но я поставил валидацию на место и сделал ее гораздо более надежным процессом, но у меня все еще остается масса данных, которые не в состоянии выполнить свое назначение, и я, кажется, потерпел поражение от запросапределы cosmosDB.

Так что мой вопрос.Как я могу запросить cosmosDB, чтобы найти документ со строками, которые превышают 200 символов?

Вот пример JSON, который я пытаюсь сделать запрос, хранится в cosmosDB

{
    "title": "My Json Data",
    "questions": [
      {
        "type": "Options",
        "position": 0,
        "text": "POTENTIONALLY LARGE STRING",
        "supportingQuestion": "POTENTIONALLY LARGE STRING",
        "options": [
          {
            "position": 0,
            "text": "Strongly Agree"
          },
          {
            "position": 1,
            "text": "Agree"
          },
          {
            "position": 2,
            "text": "Neutral"
          },
          {
            "position": 3,
            "text": "Disagree"
          },
          {
            "position": 4,
            "text": "Strongly Disagree"
          }
        ],
      },
      {
        "type": "Options",
        "position": 1,
        "text": "POTENTIONALLY LARGE STRING",
        "supportingQuestion": "POTENTIONALLY LARGE STRING",
        "options": [
          {
            "position": 0,
            "text": "Strongly Agree"
          },
          {
            "position": 1,
            "text": "Agree"
          },
          {
            "position": 2,
            "text": "Neutral"
          },
          {
            "position": 3,
            "text": "Disagree"
          },
          {
            "position": 4,
            "text": "Strongly Disagree"
          }
        ],
      }
    ]
}

Я попытался поискать вокруг, чтобы увидеть, есть ли какие-нибудь операторы, которые я могу использовать для космоса иМне совсем не везет.

С помощью подобных запросов я могу искать конкретных нарушителей, но не общих нарушителей, на которых я нахожусь.

ВЫБРАТЬ * ОТ c ГДЕ ARRAY_CONTAINS (c.questions, {text: "Мой вопросtext "}, true)

Есть ли способ поиска текста c.questions> 200?

Я также пытался загрузить каждый документ локально, используя инструмент миграции, поставляемый Microsoft, поэтому я мог попытаться выполнить их просмотр.

        // Set some common query options.
        FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 };

        IQueryable<Forms> formQuery = client.CreateDocumentQuery<Forms>(
            UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId), queryOptions)
            .Where(f => f.FormType == "Evaluation");

        // Execute the query synchronously. 
        Console.WriteLine("Running LINQ query...");
        foreach (Forms FormType in formQuery)
        {
            Console.WriteLine($"\tRead {FormType}");
        }

        // Now execute the same query using direct SQL.
        IQueryable<Forms> formQueryInSql = client.CreateDocumentQuery<Forms>(
            UriFactory.CreateDocumentCollectionUri(DatabaseId, CollectionId),
            selectLabel.Text + @" " + QueryBox.Text,
            //"SELECT * FROM c",
            queryOptions);

        Console.WriteLine("Running direct SQL query...");
        foreach (Forms Item in formQueryInSql)
        {
            Console.WriteLine($"\tRead {Item.Id}");
        }

Этот код прекрасно работает с небольшими наборами данных, но не совсем хорошо с большими наборами данных, которые я использую.Он зависает и вылетает

Есть ли какой-нибудь более простой запрос, который я могу использовать в интерфейсе cosmosDB, чтобы получить то, что мне нужно?Или мне нужно подумать о получении этого с помощью какого-нибудь умного кода?

1 Ответ

0 голосов
/ 19 июня 2019

Похоже, вы используете SQL API, поэтому я отвечу на основании этого предположения.Вы можете создать запрос, который перебирает массив вопросов и извлекает искомые длины строк.

Вы можете запускать эти запросы через портал или через API, однако портал иногда предпочитает работать только с подмножеством данных, поэтому результаты могут быть неточными.Это означает, что с большим набором данных вы, вероятно, захотите запустить их из кода, но работа по сортировке значений будет перенесена в CosmosDB вместо того, чтобы пытаться загрузить все на вашем локальном компьютере.

SELECT 
    c.position,
    c.text,
    LENGTH(c.text) AS textLength,
    c.supportingQuestion,
    LENGTH(c.supportingQuestion) AS supportingQuestionLength
FROM c IN items.questions
WHERE LENGTH(c.text) > 200 OR LENGTH(c.supportingQuestion) > 200

Ваш тест Json создает этот вывод (я уменьшил фильтр до 20, чтобы получить результаты):

[
    {
        "position": 0,
        "text": "POTENTIONALLY LARGE STRING",
        "textLength": 26,
        "supportingQuestion": "POTENTIONALLY LARGE STRING",
        "supportingQuestionLength": 26
    },
    {
        "position": 1,
        "text": "POTENTIONALLY LARGE STRING",
        "textLength": 26,
        "supportingQuestion": "POTENTIONALLY LARGE STRING",
        "supportingQuestionLength": 26
    }
]

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

SELECT 
    MAX(LENGTH(c.text)) AS textLength,
    MAX(LENGTH(c.supportingQuestion)) AS supportingQuestionLength
FROM c IN items.questions

Вывод:

[
    {
        "textLength": 26,
        "supportingQuestionLength": 26
    }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...