1

RavenDBでは、特定の基準に一致するプロパティをカウントする必要がある場合を理解しています。それを達成できます

  1. グループ化したいプロパティ名に対してファセットを作成することにより、
  2. 次に、上記のプロパティと where 句で必要なプロパティのインデックスを作成します。
  3. 最後に、上記のインデックスを使用してクエリを発行します。ToFacets 拡張機能を使用してクエリを具体化します。

しかし、ドキュメントの値のコレクションであるプロパティに対する述語が where 句に含まれている場合はどうなるでしょうか。入れ子になったプロパティをコレクションから親ドキュメントに対するインデックスに追加すると、親ドキュメントのプロパティに対するファセット カウントが正確にならないのでしょうか?

例えば

public class Camera { 
  string Make { get;set; }
  string Model { get;set; } 
  double Price { get;set; }
  IEnumerable<string> Showrooms { get;set; }
}

私のクエリは次のようになります

(from camera in session.Query<Camera, Camera_Facets>() 
 where camera.Price < 100 && camera.ShowRooms.Any(s => s.In("VIC", "ACT", "QLD")) 
 select new { 
       camera.Make, 
       camera.Model, 
       camera.Price}
 ).ToFacets("facets/CameraFacets");

更新:失敗したテストは次のとおりです

[TestFixture]
public class FacetedSearchWhenQueryingNestedCollections
{
    public class Car
    {
        public Car()
        {
            Locations = new List<string>();
        }

        public string Id { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
        public double Price { get; set; }
        public IEnumerable<string> Locations { get; set; }
    }

    public class Car_Facets : AbstractIndexCreationTask<Car>
    {
        public Car_Facets()
        {
            Map = cars => from car in cars
                          select new {car.Make, car.Model, car.Price};
        }
    }

    private static IDocumentSession OpenSession
    {
        get { return new EmbeddableDocumentStore {RunInMemory = true}.Initialize().OpenSession(); }
    }

    [Test]
    public void CanGetFacetsWhenQueryingNesetedCollectionValues()
    {
        var cars = Builder<Car>.CreateListOfSize(50)
            .Section(0, 10)
                .With(x => x.Model = "Camry")
                .With(x => x.Make = "Toyota")
                .With(x => x.Price = 2000)
                .With(x => x.Locations = new[] {"VIC", "ACT"})
            .Section(11, 20)
                .With(x => x.Model = "Corolla")
                .With(x => x.Make = "Toyota")
                .With(x => x.Price = 1000)
                .With(x => x.Locations = new[] { "NSW", "ACT" })
            .Section(21, 30)
                .With(x => x.Model = "Rx8")
                .With(x => x.Make = "Mazda")
                .With(x => x.Price = 5000)
                .With(x => x.Locations = new[] { "ACT", "SA", "TAS" })
            .Section(31, 49)
                .With(x => x.Model = "Civic")
                .With(x => x.Make = "Honda")
                .With(x => x.Price = 1500)
                .With(x => x.Locations = new[] { "QLD", "SA", "TAS" })
            .Build();

        IDictionary<string, IEnumerable<FacetValue>> facets;

        using(var s = OpenSession)
        {
            s.Store(new FacetSetup { Id = "facets/CarFacets", Facets = new List<Facet> { new Facet { Name = "Model" }, new Facet { Name = "Make" }, new Facet { Name = "Price" } } });
            s.SaveChanges();

            IndexCreation.CreateIndexes(typeof(Car_Facets).Assembly, s.Advanced.DocumentStore);

            foreach (var car in cars)
                s.Store(car);

            s.SaveChanges();

            s.Query<Car, Car_Facets>().Customize(x => x.WaitForNonStaleResults()).ToList();

            facets = s.Query<Car, Car_Facets>()
                .Where(x => x.Price < 3000)
                .Where(x => x.Locations.Any(l => l.In("QLD", "VIC")))
                .ToFacets("facets/CarFacets");
        }

        Assert.IsNotNull(facets);
        Assert.IsTrue(facets.All(f => f.Value.Count() > 0));
        Assert.IsTrue(facets.All(f => f.Value.All(x => x.Count > 0)));
    }

    [TearDown]
    public void ClearData()
    {
        using(var s = OpenSession)
        {
            foreach (var car in s.Query<Car>().ToList())
                s.Delete(car);

            s.SaveChanges();
        }
    }
}

しかし、クエリを次のように変更すると。(ネストされたコレクションをクエリしない)

    facets = s.Query<Car, Car_Facets>()
                .Where(x => x.Price < 3000)
                .ToFacets("facets/CarFacets");

これで、ディクショナリに 3 つの列挙が取得され、すべて値が含まれます。

4

1 に答える 1

2

インデックスを次のように変更すると

    public class Car_Facets : AbstractIndexCreationTask<Car>
    {
        public Car_Facets()
        {
            Map = cars => from car in cars
                          from location in car.Locations
                          select new {car.Make, car.Model, car.Price, Location = location};
        }
    }

プロジェクション用のクラスを作成する

    public class CarOnLocation
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public double Price { get; set; }
        public string Location { get; set; }
    }

そして、次のようにクエリします

    facets = s.Query<Car, Car_Facets>().AsProjection<CarOnLocation>()
                .Where(x => x.Price < 3000)
                .Where(x => x.Location.In("QLD", "VIC"))
                .ToFacets("facets/CarFacets");

できます。

于 2011-10-27T23:05:37.050 に答える