Azure Поиск - Коллекция запросов GeographyPoint - PullRequest
0 голосов
/ 05 января 2020

Я пытаюсь запросить коллекцию GeographyPoint в заданном диапазоне из моего индекса. Я использую Azure Поиск.

Мой индекс содержит список GeographyPoint

public class Parent
{
     public List<Child> Coordinates {get; set;}
}


public class Child
{ 
     public GeographyPoint Coordinates { get; set; }
}

Я знаю, что если в индексе есть одно свойство с именем location, вы можете запросить его с помощью чего-то вроде :

$ filter = geo.distance (location, geography'POINT (-82.51571 31.89063) ') le 0.1524

но как выполнить запрос к коллекции? Я пытался использовать любые / все фильтры, такие как:

$ filter = geo.distance (IndexedCompany / Offices / any (c: c / PhysicalAddress / Coordinates), geography'POINT (- 82.51571 31.89063) ') le 0.1524

но я получаю ошибку: "Недопустимое выражение: выражение запроса Любая / Все должно вычисляться в одно логическое значение. \ R \ nПараметр имени: $ filter "

Любая помощь в том, как запросить коллекцию GeographyPoint, будет очень признательна.

1 Ответ

2 голосов
/ 09 января 2020

Проблема в том, как вы создали свой фильтр. Давайте разберем его с помощью типов, так как это самый простой способ увидеть, где что-то пошло не так.

$filter=geo.distance(IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates), geography'POINT(-82.51571 31.89063)') le 0.1524

Начиная с внешней стороны, самое верхнее выражение в фильтре должно быть Boolean, и это проверяется здесь, потому что вы сравниваете geo.distance (который возвращает Edm.Double) с буквальным расстоянием, используя le. Так что с этой частью все в порядке.

Далее, давайте посмотрим на geo.distance. Он принимает две точки типа Edm.GeographyPoint и возвращает Edm.Double. Второй параметр - это буквальная точка, так что это нормально, но первый параметр - нет. Давайте посмотрим на это дальше.

Первым параметром geo.distance здесь является выражение IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates). Хотя это действительно оператор, вы можете думать о any как о некоторой функции, которая возвращает логическое значение. Это было бы проблемой, потому что geo.distance ожидает точку, а не логическое значение. Это наш первый ключ к пониманию того, что здесь не так, но на самом деле это не объясняет сообщение об ошибке, которое вы видите. Давайте копать дальше, чтобы понять это.

Предположим на данный момент, что выражение IndexedCompany/Offices/any(c: c/PhysicalAddress/Coordinates) было вашим целым фильтром. Вы все равно получите такое же сообщение об ошибке: "Invalid expression: The Any/All query expression must evaluate to a single boolean value." Чтобы понять почему, рассмотрите то, что any и all ожидают с точки зрения типов. Каждый из них перебирает коллекцию некоторого типа, применяя предикат в форме лямбда-выражения к каждому элементу. Это лямбда-выражение в этом случае - c/PhysicalAddress/Coordinates, которое (я предполагаю) - Edm.GeographyPoint, а не логическое значение.

Делая шаг назад, это помогает подумать о кардинальности, которая здесь задействована. Каждый документ содержит компанию, у которой есть много офисов, каждый из которых имеет географическое местоположение. Я предполагаю, что цель состоит в том, чтобы сопоставить весь документ в случае, если любая из этих координат соответствует фильтру. В этом случае вам просто нужно переупорядочить части вашего запроса так, чтобы типы и мощности совпадали:

$filter=IndexedCompany/Offices/any(office: geo.distance(office/PhysicalAddress/Coordinates, geography'POINT(-82.51571 31.89063)') le 0.1524)

Фильтр все еще является логическим выражением, потому что это тип any. Лямбда, переданная в any, берет Office, применяет geo.distance к своему географическому положению и сравнивает расстояние с требуемым значением. Теперь все проверяет тип и итерация происходит в нужном месте.

Пример: поиск = *

"value": [
    {
        "@search.score": 1,
        "id": "myid1",
        "pts": [
            {
                "type": "Point",
                "coordinates": [ 0, 0 ],
                "crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
            },
            {
                "type": "Point",
                "coordinates": [ 0, 1 ],
                "crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
            }
        ]
    },
    {
        "@search.score": 1,
        "id": "myid2",
        "pts": [
            {
                "type": "Point",
                "coordinates": [ 0, 10 ],
                "crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
            },
            {
                "type": "Point",
                "coordinates": [ 0, 11 ],
                "crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
            }
        ]
    }
]

Пример $ filter = pts / any ( pt: geo.distance (pt, geography'POINT (0 2) ') le 111.3192394008)

"value": [
    {
        "@search.score": 1,
        "id": "myid1",
        "pts": [
            {
                "type": "Point",
                "coordinates": [ 0, 0 ],
                "crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
            },
            {
                "type": "Point",
                "coordinates": [ 0, 1 ],
                "crs": { "type": "name", "properties": { "name": "EPSG:4326" } }
            }
        ]
    }
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...