RevenDBサイトの例に従って、私はこれを思いついた:
public class Place_ByLocationsAndCategoryId : AbstractIndexCreationTask<Place> {
public Place_ByLocationsAndCategoryId() {
Map = places => from p in places
select new { p.Categories, _ = Raven.Database.Indexing.SpatialIndex.Generate(p.Location.Lat, p.Location.Lng) };
}
}
場所は次のようになります。
Place {
string Id;
List<Category> Categories;
...
}
カテゴリは次のようになります。
Category {
string Id;
string Name;
...
}
lat / lngの特定の半径内の場所でクエリを実行し、特定のカテゴリを含むようにインデックスを作成するにはどうすればよいですか?
私は次のように上記のインデックスをクエリしようとしました:
var placesFromDb = RavenSession.Advanced.LuceneQuery<Place>("Place/ByLocationsAndCategoryId").WhereIn("Id", new []{cat.Id}).WithinRadiusOf(radius: 5, latitude: Lat, longitude: Lng).ToList<Place>();
クエリは処理されますが、結果は返されません(返される結果があることがわかっている場合。エラーはおそらく.WhereIn()
ステートメントにありますが、使用しようとする.Where(x => x.Categories.Any(c => c.Id == id))
と、廃止されたことを示すビルドエラーが発生しました。
- アップデート -
インデックスをこれに切り替えました(Ayendeが推奨したように)
public Place_ByLocationsAndCategoryId() {
Map = places => from p in places
select new { Categories_Id = p.Categories.Select(x => x.Id), _ = Raven.Database.Indexing.SpatialIndex.Generate(p.Location.Lat, p.Location.Lng) };
}
次のように、ドキュメントストアにインデックスを作成します。
IndexCreation.CreateIndexes(typeof(Place_ByLocationsAndCategoryId).Assembly, Store);
私はそれを次のように照会します:
var placesFromDb = RavenSession.Advanced.LuceneQuery<Place>("Place/ByLocationsAndCategoryId").WhereEquals("Categories_Id ", cat.Id).WithinRadiusOf(radius: 15, latitude: Lat, longitude: Lng).ToList<Place>();
RavenDB自体のインデックスは次のようになります。
docs.Places
.Select(p => new {Categories_Id = p.Categories
.Select(x => x.Id), _ = SpatialIndex.Generate(((System.Double)(p.Location.Lat)), ((System.Double)(p.Location.Lng)))})
クエリは実行されているように見えますが、結果は0になります(検索する場所があることはわかっています)。私が気づいたことの1つは、モデルのLatおよびLngデータ型がfloatであるのに対し、インデックスがDoubleに設定されているように見えることです。
このようにインデックスに座標をキャストしようとしても、機能しません。
public Place_ByLocationsAndCategoryId() {
Map = places => from p in places
select new { Categories_Id = p.Categories.Select(x => x.Id), _ = Raven.Database.Indexing.SpatialIndex.Generate((float)p.Location.Lat, (float)p.Location.Lng) };
}
そこで、ダブルを使用するようにモデルを切り替えました。それでも0の結果を返します。
--更新2--
インデックスのカテゴリ部分を削除し、空間部分だけをクエリすると、場所が返されます。カテゴリ部分が計画どおりに機能していないようです。
それが役立つ場合は、保存されたドキュメントがどのように部分的に見えるかを次に示します(JSONビュー)。
{
"Id": "4dca6d56d22da18f4e626f54",
"Name": "焼肉",
"Categories": [
{
"PlaceCategories": null,
"Name": "Korean Restaurant",
"Icon": "korean.png",
"Id": "4bf58dd8d48988d113941735",
"IsPrimary": true
}
],
"Location": {
"Lat": "35.6709824",
"Lng": "139.374588"
},
...
}
(注:カテゴリはリストです。カテゴリには、PlaceCategoriesという名前の独自のListプロパティにサブカテゴリを含めることができます)
--更新3--
管理スタジオからのインデックスエラーは次のとおりです。
Places/ByLocationsAndCategoryId Cannot convert type 'string' to 'float' 6/27/2012 places/1025 ... and repeats 50 times
空間ジェネレーターがダブルを望んでいたように見えたので、モデルをフロートからダブルに変更しました。ログにエラー(過去50を表示できない)があり、「タイプ「文字列」を「フロート」に変換できません」と表示されている可能性があります
以前のモデルでは、Lat/Lngがフロートでした。文字列はどこから来ていますか?