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;
    ...
}

如何建立我的索引,以便我可以按纬度/经度的给定半径内的地点进行查询,并包含给定的类别?

我试图像这样查询上面的索引:

 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 个结果(我知道有地方可以找到)。我注意到的一件事是我的模型中的 Lat 和 Lng 数据类型是浮点数,而索引似乎设置为 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"
  },
  ...
}

(注意:Categories就是List,categories可以有子categories,在自己的List属性中命名为PlaceCategories)


--更新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 中使用空间索引,你必须将你的坐标存储为双精度(我的最初是浮点数)。我确实更改为双精度,但必须编写一个脚本来遍历数据库中的所有文档并将坐标转换为双精度。

在那之后像冠军一样工作。

于 2012-06-28T13:28:30.047 回答