2016-10-24 2 views
1

Я пытаюсь получить количество для моего местоположения внутри многоугольника. Вот моя ХП:Выполнение ST_WITHIN с использованием хранимой процедуры в документеdb

function count(poly) { 
var collection = getContext().getCollection(); 
var query = {query: 'Select f.id from f WHERE ST_WITHIN(f.location, @poly)', 
      parameters: [{name: '@poly', value: poly}]}; 

var isAccepted = collection.queryDocuments(
    collection.getSelfLink(), 
    query, 
    function (err, docs, options) { 
     if (err) throw err; 
     if (!docs || !docs.length) getContext().getResponse().setBody('no docs found'); 
     else getContext().getResponse().setBody(docs.length); 
    }); 

if (!isAccepted) throw new Error('The query was not accepted by the server.');} 

Когда я выполнить тот же запрос в проводнике запросов, я получаю результаты, но через хранимые процедуры, его возвращение «не найдены документов». Он возвращает результаты для более простых запросов, но для этого также возвращаемый максимальный счет всегда равен 100. Не уверен, что я делаю неправильно.

Заранее спасибо.

P.S .: Я попытался использовать ST_DISTANCE для этих координат. Он вернул счет как 100 (максимальное значение), но совсем не работает для ST_WITHIN.

Редактировать: Не работает. Так что я пробовал this, как описано в официальном примере для подсчета результатов. И вуаля !! Это сработало. Поэтому я перешел к следующему шагу, чтобы подсчитать все местоположения во всех полигонах, которые у меня были локально, было слишком много круговых поездок, чтобы получить счет для каждого полигона. Но вызов той же функции из цикла ничего не возвращает. Я уже тестировал каждый запрос массива в studiodb studio, и он возвращает результаты. Пожалуйста помоги!!! Код для новой процедуры:

function countABC(filterQueryArray) { 

var results = []; 
for (i = 0; i < filterQueryArray.length; i++) { 
    countnew(filterQueryArray[i].QueryString, ""); 

} 
getContext().getResponse().setBody(results); 

function countnew(filterQuery, continuationToken) { 
    var collection = getContext().getCollection(); 
    var maxResult = 50000; 
    var result = 0; 

    tryQuery(continuationToken); 
    function tryQuery(nextContinuationToken) { 
     var responseOptions = { 
      continuation: nextContinuationToken, 
      pageSize: maxResult 
     }; 

     if (result >= maxResult || !query(responseOptions)) { 
      setBody(nextContinuationToken); 
     } 
    } 

    function query(responseOptions) { 
     return (filterQuery && filterQuery.length) ? 
      collection.queryDocuments(collection.getSelfLink(), filterQuery, responseOptions, onReadDocuments) : 
      collection.readDocuments(collection.getSelfLink(), responseOptions, onReadDocuments); 
    } 

    function onReadDocuments(err, docFeed, responseOptions) { 
     if (err) { 
      throw 'Error while reading document: ' + err; 
     } 

     result += docFeed.length; 

     if (responseOptions.continuation) { 
      tryQuery(responseOptions.continuation); 
     } else { 
      setBody(null); 
     } 
    } 


    function setBody(continuationToken) { 
     var body = { 
      count: result, 
      continuationToken: continuationToken 
     };    
     results.push(body); 
    } 
} 

}

+0

Можете ли вы показать 'poly'? –

+0

{ '' координаты: [[[- 72.56244522109489,42.195626800619728], [- 72.5503062656826,42.195626160743714], [- 72.550316627691416,42.186632945589423], [- 72.562453856102479,42.186633585263621], [- 72.56244522109489,42.195626800619728]]], 'тип':» Polygon '} – Leo

+0

Вы пробовали это без абстракции параметров? Мне интересно, если это проблема с заменой @poly? –

ответ

0

С новым sproc, это не полезно, чтобы установить результат после цикла, так как в это время никаких запросов выполняются (результаты массив будет пустым). Идея заключается в том, что все вызовы CRUD/запросов помещаются в очередь и выполняются после завершения сценария, который их поставил в очередь (в данном случае основного скрипта).

Установка результата/органа должна быть выполнена из обратного вызова. Это уже частично сделано, но есть проблема, что для каждого вызова countnew переменная «result» сбрасывается на 0. По существу, «var result = 0» необходимо выполнить в главном скрипте.

Кроме того, не рекомендуется использовать петли, подобные циклу «для», когда он вызывает CRUD/запросы в цикле, не дожидаясь завершения предыдущего CRUD/запроса (из-за асинхронного характера), в противном случае проверка isAccepted не является надежной , Что рекомендуется его сериализовать эту петлю, что-то вроде этого:

var result = 0; 
 
step(); 
 

 
function step() { 
 
    if (filterQueryArray.length == 0) setBody(null); 
 
    else { 
 
    var query = filterQueryArray.shift(); 
 
    
 
    // process current query. In the end (from callback), call step() again. 
 
    } 
 
}

Имеет ли это смысл?