Проблема в том, как вы создали свой фильтр. Давайте разберем его с помощью типов, так как это самый простой способ увидеть, где что-то пошло не так.
$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" } }
}
]
}
]