Função OData search.in em Pesquisa Cognitiva Azure

Um cenário comum nas expressões de filtro OData é verificar se um único campo em cada documento é igual a um de muitos valores possíveis. Por exemplo, é assim que algumas aplicações implementam o corte de segurança -- verificando um campo contendo um ou mais IDs principais contra uma lista de IDs principais que representam o utilizador que emite a consulta. Uma maneira de escrever uma consulta como esta é usar o eq e or os operadores:

    group_ids/any(g: g eq '123' or g eq '456' or g eq '789')

No entanto, há uma maneira mais curta de escrever isto, usando a search.in função:

    group_ids/any(g: search.in(g, '123, 456, 789'))

Importante

Além de ser mais curto e fácil de ler, o uso search.in também proporciona benefícios de desempenho e evita certas limitações de tamanho dos filtros quando há centenas ou mesmo milhares de valores para incluir no filtro. Por esta razão, recomendamos vivamente a utilização search.in , em vez de uma disjunção mais complexa das expressões de igualdade.

Nota

A versão 4.01 da norma OData introduziu recentemente o in operador, que tem um comportamento semelhante ao da search.in função na Azure Cognitive Search. No entanto, a Azure Cognitive Search não suporta este operador, pelo que deve utilizar a search.in função.

Syntax

O seguinte EBNF (Formulário Backus-Naur Alargado) define a gramática da search.in função:

search_in_call ::=
    'search.in(' variable ',' string_literal(',' string_literal)? ')'

Está também disponível um diagrama de sintaxe interativo:

A search.in função testa se um determinado campo de cordas ou variável de alcance é igual a uma de uma determinada lista de valores. A igualdade entre a variável e cada valor da lista é determinada de forma sensível a casos, da mesma forma que para o eq operador. Portanto, uma expressão como search.in(myfield, 'a, b, c') é equivalente a myfield eq 'a' or myfield eq 'b' or myfield eq 'c', exceto que search.in vai produzir um desempenho muito melhor.

Existem duas sobrecargas da search.in função:

  • search.in(variable, valueList)
  • search.in(variable, valueList, delimiters)

Os parâmetros são definidos no quadro seguinte:

Nome do parâmetro Tipo Description
variable Edm.String Uma referência de campo de cordas (ou uma variável de alcance sobre um campo de recolha de cordas no caso search.in de ser usado dentro de uma any ou all expressão).
valueList Edm.String Uma cadeia contendo uma lista delimitada de valores que corresponda ao variable parâmetro. Se o delimiters parâmetro não for especificado, os delimiters predefinidos são o espaço e a vírgula.
delimiters Edm.String Uma corda onde cada personagem é tratado como um separador ao analisar o valueList parâmetro. O valor predefinido deste parâmetro é ' ,' o que significa que quaisquer valores com espaços e/ou vírgulas entre eles serão separados. Se precisar de utilizar separadores que não espaços e vírgulas porque os seus valores incluem esses caracteres, pode especificar delimiters alternativos, como '|' neste parâmetro.

Desempenho de search.in

Se utilizar search.in, pode esperar tempo de resposta de segundo quando o segundo parâmetro contiver uma lista de centenas ou milhares de valores. Não existe um limite explícito no número de itens a que pode passar search.in, embora ainda esteja limitado pelo tamanho máximo do pedido. No entanto, a latência vai crescer à medida que o número de valores aumenta.

Exemplos

Encontre todos os hotéis com nome igual a 'Sea View motel' ou 'Budget hotel'. As frases contêm espaços, que é um delimiter padrão. Pode especificar um limontinho alternativo em cotações simples como o terceiro parâmetro de cadeia:

    search.in(HotelName, 'Sea View motel,Budget hotel', ',')

Encontre todos os hotéis com nome igual a 'Sea View motel' ou 'Budget hotel' separados por '|'):

    search.in(HotelName, 'Sea View motel|Budget hotel', '|')

Encontre todos os hotéis com quartos com a etiqueta 'wifi' ou 'tub':

    Rooms/any(room: room/Tags/any(tag: search.in(tag, 'wifi, tub')))

Encontre uma correspondência em frases dentro de uma coleção, tais como "toalheiros aquecidos" ou "secador de cabelo incluído" em etiquetas.

    Rooms/any(room: room/Tags/any(tag: search.in(tag, 'heated towel racks,hairdryer included', ','))

Encontre todos os hotéis sem a etiqueta 'motel' ou 'cabine':

    Tags/all(tag: not search.in(tag, 'motel, cabin'))

Passos seguintes