c# - 如何正确构建 RavenDB 空间索引,同时检查是否有任何 List<objects> 匹配?

标签 c# linq ravendb

example on the RevenDB site 之后,我想到了这个:

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 数据类型是 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) };
}

所以我将我的模型切换为使用 double ;仍然返回 0 个结果。


--更新2--

如果我删除索引的类别部分,并只查询空间部分,它会返回地点。类别部分似乎没有按计划运行。

如果有帮助,以下是存储文档的部分外观(JSON View ):

{
  "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可以有子类别,在自己的List属性中命名为PlaceCategories)


--更新3--

这是管理工作室的索引错误:

Places/ByLocationsAndCategoryId 
Cannot convert type 'string' to 'float' 
6/27/2012 
places/1025
... and repeats 50 times

我已经将我的模型从浮点型更改为 double 型,因为看起来空间生成器需要 double 型。很有可能日志中有一些错误(看不到超过 50),指出“无法将类型‘string’转换为‘float’

我很好奇,在我之前的模型中,我的 Lat/Lng 是 float 。字符串从哪里来?

最佳答案

你想要这样:

索引:

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>();

关于c# - 如何正确构建 RavenDB 空间索引,同时检查是否有任何 List<objects> 匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11209518/

相关文章:

c# - UserPrincipals.GetAuthorizationGroups 枚举组时发生错误 (1301)。升级到 Server 2012 域 Controller 后

c# - 具有一个类的多个公共(public)别名的类库

c# - LINQ to Entities 查询以展平结果并选择和分组所需信息

c# - Linq 查询连接不起作用

c# - Ravendb mapreduce 按多个字段分组

nhibernate - 寻找有关嵌入式.NET数据库(例如db4o,NHibernate或RavenDB)的指南

c# - RavenDb 存储和检索无类对象 (json)

c# - 如何在 NSubstitute 中伪造一个对象并忽略其方法的内部实现?

c# - 什么可能导致使用 C# 从 Gmail SMTP 发送的邮件无法到达 - 不会引发异常

c# - LINQ IEnumerable<T> 内存结构