SpatialQuery для поиска по местоположению с использованием Lucene - PullRequest
2 голосов
/ 27 июня 2009

У моего индекса люцены есть поля широты и долготы, проиндексированные следующим образом:

doc.Add(new Field("latitude", latitude.ToString() , Field.Store.YES, Field.Index.UN_TOKENIZED));

doc.Add(new Field("longitude", longitude.ToString(), Field.Store.YES, Field.Index.UN_TOKENIZED));

Я хочу получить набор документов из этого индекса, у которых значения lat и long находятся в заданном диапазоне.

Как вы уже знаете, Lat и long могут быть отрицательными значениями. Как правильно хранить подписанные десятичные числа в Lucene? Даст ли упомянутый ниже подход правильные результаты или есть ли другой способ сделать это?

 Term lowerLatitude = new Term("latitude", bounds.South.ToString() );
                Term upperLatitude = new Term("latitude", bounds.North.ToString());
                RangeQuery latitudeRangeQuery = new RangeQuery(lowerLatitude, upperLatitude, true);
                findLocationQuery.Add(latitudeRangeQuery, BooleanClause.Occur.SHOULD);



                Term lowerLongitude = new Term("longitude", bounds.West.ToString());
                Term upperLongitude = new Term("longitude", bounds.East.ToString());
                RangeQuery longitudeRangeQuery = new RangeQuery(lowerLongitude, upperLongitude, true);
                findLocationQuery.Add(longitudeRangeQuery, BooleanClause.Occur.SHOULD);

Кроме того, я хотел узнать, насколько лучше ConstantScoreRangeQuery от Lucene, чем класс RangeQuery.

Столкнулся с другой проблемой в этом контексте: У меня есть один из документов в индексе со следующими 3 городами:

  • Лион, Иллинойс

    Дуб-Брук, Иллинойс

    Сан-Франциско, Калифорния

Если я введу «Лайонс, Иллинойс», тогда появится эта запись. Но если в качестве входных данных я приведу Сан-Франциско, Калифорния, то это не так.

Однако, если я сохраню города для этого документа следующим образом:

  • Сан-Франциско, Калифорния

    Лион, Иллинойс

    Дуб-Брук, Иллинойс

    и когда я даю Сан-Франциско, Калифорния, в качестве входных данных, эта запись отображается в результатах поиска.

Здесь я хочу, чтобы при вводе любого из 3-х городов я получил этот документ в результатах поиска.

Пожалуйста, помогите мне достичь этого.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 28 июня 2009

Следуя предложению Скаффмана, вы можете использовать ту же систему координат плитки , которая используется во всех популярных приложениях для карт. Выберите любой уровень масштабирования, достаточный для ваших нужд, и не забудьте дополнить его передними нулями.

Относительно RangeQuery , он медленнее, чем ConstantScoreRangeQuery, и ограничивает диапазон значений.

Относительно проблемы города-государства мы можем только строить догадки. Но первое, что нужно проверить, это то, что индексированные термины и проанализированный запрос - это то, что вы ожидаете от них.

1 голос
/ 01 июля 2009

Я думаю, что лучший способ - преобразовать / нормализовать координаты, как было предложено в предыдущем посте. Эта статья делает именно это. Это на самом деле довольно хороший объектно-ориентированный код.

По поводу вашей второй проблемы. Я предполагаю, что у вас есть какая-то проблема с анализатором. Используете ли вы один и тот же анализатор для индексации и запросов? Какие токенизаторы вы используете?

Я рекомендую использовать Luke для проверки вашего сгенерированного индекса, чтобы увидеть, какие токены действительно доступны для поиска.

- Hardy

0 голосов
/ 27 июня 2009

Один из вариантов здесь - преобразовать координаты в систему, в которой нет отрицательных чисел. Например, у меня была похожая проблема для веб-приложения Google Maps для Великобритании, и я сохранил поля UK Easting / Northings (в диапазоне от 0 до 7 цифр) в Lucene вместе со значениями lat / long. Отформатировав эти восточные / северные координаты с нулями в левом нижнем углу, я мог бы выполнять запросы диапазона lucene.

Существует ли аналогичная система координат для США?

...