Skip to content

Instantly share code, notes, and snippets.

@hyrmn
Created May 16, 2016 22:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hyrmn/4aa61a6cdc0ab64926ac5901c1d52ca0 to your computer and use it in GitHub Desktop.
Save hyrmn/4aa61a6cdc0ab64926ac5901c1d52ca0 to your computer and use it in GitHub Desktop.
Querying child collections by id in RavenDB
public class Foo
{
public string Id { get; set; }
public string Name { get; set; }
public Bar[] Bars { get; set; }
}
public class Bar
{
public string Id { get; set; }
public string Name { get; set; }
}
public class FooIndex : AbstractIndexCreationTask<Foo>
{
public FooIndex()
{
Map = docs => from doc in docs
select new
{
doc.Name,
Bars_Id = doc.Bars.Select(bar => bar.Id)
};
Store(x => x.Bars.Select(b => b.Id), FieldStorage.Yes);
Index(x => x.Bars.Select(b => b.Id), FieldIndexing.Analyzed);
}
}
public class FooChildIdsNotAnalyzedIndex : AbstractIndexCreationTask<Foo>
{
public FooChildIdsNotAnalyzedIndex()
{
Map = docs => from doc in docs
select new
{
doc.Name,
BarIds = doc.Bars.Select(bar => bar.Id)
};
Store(x => x.Bars.Select(b => b.Id), FieldStorage.Yes);
Index(x => x.Bars.Select(b => b.Id), FieldIndexing.NotAnalyzed);
}
}
public class NoStaleQueriesAllowed : IDocumentQueryListener
{
public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization)
{
queryCustomization.WaitForNonStaleResults();
}
}
public class ChildCollectionQueryTests
{
private readonly EmbeddableDocumentStore documentStore;
public ChildCollectionQueryTests()
{
documentStore = new EmbeddableDocumentStore
{
Configuration =
{
RunInUnreliableYetFastModeThatIsNotSuitableForProduction = true,
RunInMemory = true
}
};
documentStore.ConfigureSerializers();
documentStore.RegisterListener(new NoStaleQueriesAllowed());
documentStore.Initialize();
}
public void searching_by_child_id_on_not_analyzed_errors()
{
new FooChildIdsNotAnalyzedIndex().Execute(documentStore.DatabaseCommands, documentStore.Conventions);
using (var session = documentStore.OpenSession())
{
var fooOne = new Foo {Id = "foos/1", Name = "First Foo", Bars = new[] {new Bar {Id = "Bars/1", Name = "Bar"}}};
var fooTwo = new Foo {Id = "foos/2", Name = "Foo the Greater"};
session.Store(fooOne);
session.Store(fooTwo);
session.SaveChanges();
var fooSearch = session.Query<Foo, FooChildIdsNotAnalyzedIndex>().Where(x => x.Bars.Any(b => b.Id == "Bars/1"));
Should.Throw<ArgumentException>(() => fooSearch.ToList());
}
}
public void can_search_child_collection_by_id_if_analyzed()
{
new FooIndex().Execute(documentStore.DatabaseCommands, documentStore.Conventions);
using (var session = documentStore.OpenSession())
{
var fooOne = new Foo {Id = "foos/1", Name = "First Foo", Bars = new[] {new Bar {Id = "Bars/1", Name = "Bar"}}};
var fooTwo = new Foo {Id = "foos/2", Name = "Foo the Greater"};
session.Store(fooOne);
session.Store(fooTwo);
session.SaveChanges();
var fooSearch = session.Query<Foo, FooIndex>().Where(x => x.Bars.Any(b => b.Id == "Bars/1"));
var foos = fooSearch.ToList();
foos.Count.ShouldBe(1);
}
}
}
@hyrmn
Copy link
Author

hyrmn commented May 16, 2016

Note the failure here is that, while Raven's recommendation is to store Ids as NotAnalyzed, you must store them Analyzed if you're storing a collection... which makes sense. an id (or any field) in a child collection is just a piece of data as far as Raven cares.

Also, note the mapped field must be called Bars_Id. This is due to the convention-based naming Raven uses

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment