Modelo de tipos de dados complexos na Pesquisa Cognitiva Azure

Conjuntos de dados externos usados para povoar um índice de Pesquisa Cognitiva azul podem vir em muitas formas. Por vezes incluem subestruturas hierárquicas ou aninhadas. Exemplos podem incluir vários endereços para um único cliente, múltiplas cores e tamanhos para um único SKU, múltiplos autores de um único livro, e assim por diante. Em termos de modelação, pode ver estas estruturas referidas como tipos de dados complexos, compostos, compostos ou agregados . O termo Azure Cognitive Search usa para este conceito é um tipo complexo. Na Pesquisa Cognitiva Azure, os tipos complexos são modelados usando campos complexos. Um campo complexo é um campo que contém crianças (sub-campos) que podem ser de qualquer tipo de dados, incluindo outros tipos complexos. Isto funciona de forma semelhante aos tipos de dados estruturados numa linguagem de programação.

Os campos complexos representam um único objeto no documento, ou uma matriz de objetos, dependendo do tipo de dados. Os campos de tipo Edm.ComplexType representam objetos únicos, enquanto os campos de tipo Collection(Edm.ComplexType) representam matrizes de objetos.

A Azure Cognitive Search suporta nativo tipos e coleções complexas. Estes tipos permitem-lhe modelar quase todas as estruturas JSON num índice de Pesquisa Cognitiva Azure. Em versões anteriores de Azure Cognitive Search APIs, apenas conjuntos de linha achatados poderiam ser importados. Na versão mais recente, o seu índice pode agora corresponder mais de perto aos dados de origem. Por outras palavras, se os seus dados de origem tiverem tipos complexos, o seu índice também pode ter tipos complexos.

Para começar, recomendamos o conjunto de dados do Hotels, que pode carregar no assistente de dados Import no portal Azure. O assistente deteta tipos complexos na fonte e sugere um esquema de índice baseado nas estruturas detetadas.

Nota

O suporte para tipos complexos tornou-se geralmente disponível a partir de api-version=2019-05-06.

Se a sua solução de pesquisa for construída sobre soluções anteriores de conjuntos de dados achatados numa recolha, deverá alterar o seu índice para incluir tipos complexos como suportado na versão API mais recente. Para obter mais informações sobre a atualização das versões API, consulte Upgrade para a versão mais recente da API REST ou Upgrade para a versão mais recente .NET SDK.

Exemplo de uma estrutura complexa

O seguinte documento JSON é composto por campos simples e campos complexos. Campos complexos, tais como Address e Rooms, têm sub-campos. Address tem um único conjunto de valores para esses sub-campos, uma vez que é um único objeto no documento. Em contraste, Rooms tem vários conjuntos de valores para os seus sub-campos, um para cada objeto na coleção.

{
  "HotelId": "1",
  "HotelName": "Secret Point Motel",
  "Description": "Ideally located on the main commercial artery of the city in the heart of New York.",
  "Tags": ["Free wifi", "on-site parking", "indoor pool", "continental breakfast"],
  "Address": {
    "StreetAddress": "677 5th Ave",
    "City": "New York",
    "StateProvince": "NY"
  },
  "Rooms": [
    {
      "Description": "Budget Room, 1 Queen Bed (Cityside)",
      "RoomNumber": 1105,
      "BaseRate": 96.99,
    },
    {
      "Description": "Deluxe Room, 2 Double Beds (City View)",
      "Type": "Deluxe Room",
      "BaseRate": 150.99,
    }
    . . .
  ]
}

Indexação de tipos complexos

Durante a indexação, você pode ter um máximo de 3000 elementos em todas as coleções complexas dentro de um único documento. Um elemento de uma coleção complexa é um membro dessa coleção, por isso, no caso dos Quartos (a única coleção complexa no exemplo do Hotel), cada quarto é um elemento. No exemplo acima, se o "Motel Secret Point" tivesse 500 quartos, o documento do hotel teria 500 elementos de quarto. Para coleções complexas aninhadas, cada elemento aninhado também é contado, além do elemento exterior (progenitor).

Este limite aplica-se apenas a coleções complexas, e não a tipos complexos (como Address) ou coleções de cordas (como Tags).

Criar campos complexos

Como em qualquer definição de índice, pode utilizar o portal, REST API ou .NET SDK para criar um esquema que inclua tipos complexos.

Outros SDKs Azure fornecem amostras em Python, Java e JavaScript.

  1. Inscreva-se no portal Azure.

  2. Na página 'Visão geral' do serviço de pesquisa, selecione o separador Índices .

  3. Abra um índice existente ou crie um novo índice.

  4. Selecione o separador Campos e, em seguida, selecione adicionar o campo. Um campo vazio é adicionado. Se estiver a trabalhar com uma coleção de campos existente, desça para preparar o campo.

  5. Dê ao campo um nome e desemote o tipo para qualquer um Edm.ComplexType ou Collection(Edm.ComplexType).

  6. Selecione as elipses na extrema direita e, em seguida, selecione ou Adicione campo ou Adicione subcampo e, em seguida, atribua atributos.

Atualizar campos complexos

Todas as regras de reindexão aplicáveis aos campos em geral ainda se aplicam a campos complexos. Restaurar algumas das principais regras aqui, adicionar um campo a um tipo complexo não requer uma reconstrução de índice, mas a maioria das modificações sim.

Atualizações estruturais da definição

Pode adicionar novos sub-campos a um campo complexo a qualquer momento sem a necessidade de uma reconstrução de índices. Por exemplo, é permitido adicionar "ZipCode" ou Address "Amenities", Rooms tal como adicionar um campo de alto nível a um índice. Os documentos existentes têm um valor nulo para novos campos até que você povoe explicitamente esses campos atualizando os seus dados.

Note que dentro de um tipo complexo, cada sub-campo tem um tipo e pode ter atributos, assim como os campos de alto nível fazem

Atualizações de dados

A atualização dos documentos existentes num índice com a ação upload funciona da mesma forma para campos complexos e simples- todos os campos são substituídos. No entanto, merge (ou mergeOrUpload quando aplicado a um documento existente) não funciona da mesma forma em todos os campos. Especificamente, merge não suporta a fusão de elementos dentro de uma coleção. Esta limitação existe para coleções de tipos primitivos e coleções complexas. Para atualizar uma coleção, terá de recuperar o valor de recolha completo, fazer alterações e, em seguida, incluir a nova coleção no pedido de API index.

Pesquisar campos complexos

Expressões de pesquisa em forma livre funcionam como esperado com tipos complexos. Se algum campo pescê-lo ou sub-campo em qualquer lugar de um documento corresponder, então o documento em si é uma correspondência.

As consultas ficam mais matizadas quando se tem vários termos e operadores, e alguns termos têm nomes de campo especificados, como é possível com a sintaxe Lucene. Por exemplo, esta consulta tenta coincidir com dois termos, "Portland" e "OR", contra dois sub-campos do campo Address:

search=Address/City:Portland AND Address/State:OR

Consultas como esta não estão relacionadas com a pesquisa de texto completo, ao contrário dos filtros. Nos filtros, as consultas sobre sub-campos de uma coleção complexa são correlacionadas usando variáveis de gama em any ou all. A consulta de Lucene acima devolve documentos que contêm "Portland, Maine" e "Portland, Oregon", juntamente com outras cidades do Oregon. Isto acontece porque cada cláusula se aplica a todos os valores do seu campo em todo o documento, pelo que não existe noção de um "sub-documento atual". Para obter mais informações sobre isto, consulte filtros de recolha Understanding OData na Pesquisa Cognitiva Azure.

Selecione campos complexos

O $select parâmetro é usado para escolher quais os campos que são devolvidos nos resultados de pesquisa. Para utilizar este parâmetro para selecionar sub-campos específicos de um campo complexo, inclua o campo-mãe e o sub-campo separados por um corte (/).

$select=HotelName, Address/City, Rooms/BaseRate

Os campos devem ser marcados como Retrieváveis no índice se os quiser nos resultados de pesquisa. Apenas os campos marcados como Retrievable podem ser utilizados em comunicado $select .

Filtrar, faceta e classificar campos complexos

A mesma sintaxe do caminho OData utilizada para filtragem e pesquisas de campo também pode ser usada para enfrentar, classificar e selecionar campos num pedido de pesquisa. Para tipos complexos, aplicam-se regras que regem quais os sub-campos que podem ser marcados como tributáveis ou facetable. Para obter mais informações sobre estas regras, consulte a referência API do Índice de Criação.

Sub-campos de rosto

Qualquer sub-campo pode ser marcado como faceta, a menos que seja do tipo Edm.GeographyPoint ou Collection(Edm.GeographyPoint). .

As contagens de documento devolvidas nas facetas são calculadas para o documento-mãe (um hotel), e não para os sub-documentos numa coleção complexa (quartos). Por exemplo, suponha que um hotel tenha 20 quartos de tipo "suite". Dado este parâmetro facet=Rooms/Typefaceta, a contagem de facetas será uma para o hotel, e não 20 para os quartos.

Separar campos complexos

As operações de classificação aplicam-se a documentos (Hotéis) e não subd documentos (Quartos). Quando você tem uma coleção de tipo complexo, como quartos, é importante perceber que você não pode classificar em quartos em tudo. Na verdade, não se pode ordenar nenhuma coleção.

Ordenar operações funcionam quando os campos têm um único valor por documento, se o campo é um campo simples, ou um sub-campo em um tipo complexo. Por exemplo, Address/City é permitido ser ordenado porque há apenas um endereço por hotel, assim $orderby=Address/City irá classificar hotéis por cidade.

Filtragem em campos complexos

Pode consultar sub-campos de um campo complexo numa expressão de filtro. Basta utilizar a mesma sintaxe do caminho OData que é usada para enfrentar, classificar e selecionar campos. Por exemplo, o seguinte filtro devolverá todos os hotéis no Canadá:

$filter=Address/Country eq 'Canada'

Para filtrar num campo de recolha complexo, pode utilizar uma expressão lambda com os any operadores e all operadores. Nesse caso, a variável de alcance da expressão lambda é um objeto com sub-campos. Pode consultar os sub-campos com a sintaxe padrão do percurso OData. Por exemplo, o seguinte filtro devolverá todos os hotéis com pelo menos um quarto de luxo e todos os quartos para não fumadores:

$filter=Rooms/any(room: room/Type eq 'Deluxe Room') and Rooms/all(room: not room/SmokingAllowed)

Tal como acontece com os campos simples de alto nível, os subtipos simples de campos complexos só podem ser incluídos em filtros se tiverem o atributo filtrado definido true na definição de índice. Para obter mais informações, consulte a referência API do Índice de Criação.

Passos seguintes

Experimente os dados do Hotels definidos no assistente de dados de importação . Você precisará da informação de ligação cosmos DB fornecida na leitura para aceder aos dados.

Com essa informação na mão, o seu primeiro passo no assistente é criar uma nova fonte de dados Azure Cosmos DB. Mais à frente no assistente, quando chegar à página do índice alvo, verá um índice com tipos complexos. Crie e carregue este índice e, em seguida, execute consultas para entender a nova estrutura.