Raven-Studio Index возвращает разные результаты в C# LINQ Query

Я изучаю RavenDB (сборка 2851, версия 2.5.0/6dce79a) из Начинаю Raven 2.x и обнаруживаю, что Raven-Studio неправильно фильтрует.

У меня есть таблица городов в моей базе данных, в которой хранится их население, местоположения и т. д. Я добавил индекс в код, используя это:

public class Cities_ByPopulation : AbstractIndexCreationTask<City>
{
   public Cities_ByPopulation()
   {
      this.Map = cities => from city in cities 
                           select new { Population = city.Population };

      // Generates as this in the RDBMS
      // docs.Cities.Select(city => new {
      //     Population = city.Population
      // })
   }
}

И зарегистрировать его с кодом IndexCreation.CreateIndex(typeof(Cities_ByPopulation).Assembly, documentStore).

Проблема 1 — Raven Studio не фильтрует должным образом

Теперь индекс добавлен в RavenDB, и я запускаю фильтр в поле Population [long] в Raven Studio, фильтруя от 200 000 до 500 000.

IDE не показывает результаты правильно

Как вы можете видеть, его значения полностью вытягиваются из диапазона. Я также пробовал с Population: [Lx200000 TO Lx500000], но тогда никаких результатов не появляется.

Чтобы убедиться в этом, я создал динамический индекс, но у меня та же проблема:

Фильтрация Raven Studio с динамическим индексом

Проблема 2. LINQ не фильтрует, как ожидалось

В дополнение к этому я обнаружил, что даже при необработанном запросе LINQ данные вообще не возвращаются!

// RavenStore stores a singleton, 
// so I can share across console apps in this solution
using (var store = RavenStore.GetDocumentStore())
{
    IndexCreation.CreateIndexes(typeof(Cities_ByPopulation).Assembly, store);

    const long MinRange = 200000;
    const long MaxRange = 300000;

    Debug.Assert(MinRange < MaxRange, "Ranges need swapping round!");

    // Get cities using the index
    using (var session = store.OpenSession())
    {
        var cities =
            session.Query<City>("Cities/ByPopulation")
                .Customize(x => x.WaitForNonStaleResults())
                .Where(x => x.Population > MinRange && x.Population < MaxRange);

            Console.WriteLine("Number of normal cities within population range: {0}", cities.Count());
    }

    // Get cities from raw query
    using (var session = store.OpenSession())
    {
        var cities = session.Query<City>().Where(x => x.Population > MinRange && x.Population < MaxRange);

        Console.WriteLine("Number of normal cities within population range: {0}", cities.Count());
    }

    // Output :
    // Number of normal cities within population range: 0
    // Number of normal cities within population range: 0
}

Журнал для этого запроса выглядит следующим образом

Request # 275: GET     -     1 ms - <system>   - 200 - /docs/Raven/Databases/World
Request # 276: HEAD    -     0 ms - World      - 200 - /indexes/Cities/ByPopulation
Request # 277: PUT     -     2 ms - World      - 201 - /indexes/Cities/ByPopulation
Request # 278: GET     -     0 ms - World      - 404 - /docs/Raven/Replication/Destinations
Request # 279: GET     -     6 ms - World      - 200 - /indexes/Cities/ByPopulation?&query=Population_Range%3A%7BLx200000%20TO%20Lx300000%7D&pageSize=0&operationHeadersHash=1690003523
        Query: Population_Range:{Lx200000 TO Lx300000}
        Time: 6 ms
        Index: Cities/ByPopulation
        Results: 0 returned out of 0 total.

Request # 280: GET     -     7 ms - World      - 200 - /indexes/dynamic/Cities?&query=Population_Range%3A%7BLx200000%20TO%20Lx300000%7D&pageSize=0&operationHeadersHash=1690003523
        Query: Population_Range:{Lx200000 TO Lx300000}
        Time: 6 ms
        Index: Cities/ByPopulation
        Results: 0 returned out of 0 total.

Некоторая дополнительная информация, которая может помочь в устранении неполадок

  • Данные были импортированы через импортер CSV.
  • Никакие объекты не были сохранены из приложения .NET, только для чтения.

Это может означать, что схемы не синхронизированы или БД еще не уверена в типах данных, так как метаданные {}


Вот полученный JSON из документа:

[city/1989]
{
  "Name": "Aachen",
  "CountryCode": "D",
  "Province": "Nordrhein Westfalen",
  "Population": 247113,
  "CountryId": "country/1009"
}

и класс С#:

public class City
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string CountryCode { get; set; }
        public long Population { get; set; }
        public string Province { get; set; }
        public string CountryId { get; set; }
    }
}

Еще одно обновление

Я вручную пропатчил коллекцию с помощью

this['@metadata']['Raven-Clr-Type'] = "Domain.City, Domain"

но это тоже не помогло сериализатору.

введите здесь описание изображения


person Dominic Zukiewicz    schedule 31.03.2014    source источник
comment
Ваш номер Population хранится в виде текста в RavenDB? Похоже, это потому, что вы получаете только результаты, начинающиеся с 2, 3 или 4 - строки, которые лексографически находятся между 200000 и 500000. Может быть, используемый вами импортер CSV не идентифицирует числовые столбцы автоматически?   -  person Timothy Shields    schedule 31.03.2014
comment
Хороший вопрос! Но нет, не вокруг него. Я могу воспроизвести это довольно легко, поэтому, если кто-то хочет поближе, дайте мне знать.   -  person Dominic Zukiewicz    schedule 31.03.2014
comment
Возможно, вы захотите перепроверить это. Если он выполняет числовое сравнение, почему вы получаете значения вне диапазона, но только лексикографически между вашим минимумом и максимумом? Если числовое сравнение не работает, вы также должны получить города с населением, начинающимся с 1, 5, 6, 7, 8, 9. Кроме того, значения кода страны также не отображаются в кавычках, несмотря на то, что они являются строками.   -  person Timothy Shields    schedule 31.03.2014
comment
@TimothyShields: вопрос обновлен образцом JSON и классом C#.   -  person Dominic Zukiewicz    schedule 31.03.2014


Ответы (1)


Вы должны сказать Raven, что Population — это число, потому что все значения хранятся в виде текста. Итак, в вашем индексном конструкторе напишите что-то вроде

Sort(x => x.Population , SortOptions.Long);
person esskar    schedule 31.03.2014
comment
Итак, просто чтобы уточнить; Я импортировал как CSV. Похоже, что RavenDB предположил, что это значение. Но индексу нужно дать подсказку о типе данных? Это относится только к CSV, поскольку типы данных неявны для POCO? - person Dominic Zukiewicz; 31.03.2014
comment
Нет, я думаю, вы всегда должны указывать тип сортировки; см. также ravendb.net/ docs/2.0/client-api/querying/static-indexes/ для получения дополнительных разъяснений. - person esskar; 31.03.2014
comment
Я понимаю! По умолчанию предполагается, что это строка для сортировки. Даты сортируются неявно, но необходимо указывать целые типы. Спасибо за ссылку! - person Dominic Zukiewicz; 31.03.2014