6

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がフロートでした。文字列はどこから来ていますか?

4

2 に答える 2

3

あなたはそれをこのようにしたい:

索引:

public class Place_ByLocationsAndCategoryId : AbstractIndexCreationTask<Place> {
    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) };
    }
}

クエリ:

 var placesFromDb = RavenSession.Advanced.LuceneQuery<Place>("Place/ByLocationsAndCategoryId").WhereEquals("Categories_Id ", cat.Id).WithinRadiusOf(radius: 5, latitude: Lat, longitude: Lng).ToList<Place>();
于 2012-06-26T15:13:28.597 に答える
0

それが私のモデルだったことがわかりました。将来の参考のために、Ravenで空間インデックスを使用する場合は、座標をdoubleとして格納する必要があります(元々はfloatでした)。doubleに変更しましたが、DB内のすべてのドキュメントを調べて、座標をdoubleに変換するスクリプトを作成する必要がありました。

その後、チャンピオンのように働いた。

于 2012-06-28T13:28:30.047 に答える