--
You received this message because you are subscribed to the Google Groups "RavenDB - an awesome database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/ea85d41f-78eb-4f78-84de-ce640e1ed76bn%40googlegroups.com.
from person in personsHowever, when we run this on the server side, we are operating on the shape of the server side document.
select new
{
person.Name,
Names = person.Family.Select(e => e.Name),
Query = AsJson(person).Select(x => x.Value),
};
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/86cd06f7-c382-42b1-b34e-7cd7b4f2ddacn%40googlegroups.com.
![]() | Oren Eini CEO / Hibernating Rhinos LTD
|
Hi,
You can always use dynamic indexes by using a javascript index or create the RQL by yourself.
If you want a strong type index, you can also define an additional class that meets the document's actual structure and use it in the index.
You achieve that you can either define it in a different namespace (or inside a class) or give it a different name and modify DocumentStore.Conventions.FindCollectionName
using Xunit.Abstractions;
using Autofac;
using Newtonsoft.Json.Serialization;
using Raven.Client.Documents.Indexes;
using Raven.Client.Json.Serialization.NewtonsoftJson;
using System;
using System.Collections.Generic;
using System.Linq;
using FastTests.Client;
using Xunit;
namespace FastTests.Client
{
public class TestClass : RavenTestBase
{
public TestClass(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void LoadDocumentWithRefFromIndex()
{
using (var store = GetDocumentStore(new Options
{
ModifyDocumentStore = s => s.Conventions.Serialization = new NewtonsoftJsonSerializationConventions()
{
CustomizeJsonSerializer = serializer =>
{
serializer.ContractResolver = new ContractResolver(serializer.ContractResolver);
serializer.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
serializer.ReferenceResolver = new IdReferenceResolver(serializer.ReferenceResolver);
}
}
}))
{
Person_ForSearch abstractIndexCreationTask = new Person_ForSearch();
var definition = abstractIndexCreationTask.CreateIndexDefinition();
var maps = definition.Maps; // Easy way to get RQL
store.ExecuteIndex(abstractIndexCreationTask);
store.ExecuteIndex(new RawRqlIndex());
store.ExecuteIndex(new JavaScriptIndex());
using (var session = store.OpenSession())
{
var documentReferences = new List<IRef>()
{
new PersonRef()
{
RefId = Guid.NewGuid().ToString(),
Name = "Test"
}
};
Person person = new Person
{
Id = Guid.NewGuid().ToString(),
Name = "Bob",
Family = documentReferences.OfType<PersonRef>().ToList(),
DocumentReferences = documentReferences,
};
session.Store(person);
session.SaveChanges();
}
WaitForIndexing(store);
WaitForUserToContinueTheTest(store);
using (var session = store.OpenSession())
{
var documentQuery = session.Advanced.DocumentQuery<Person_ForSearch.Result, Person_ForSearch>()
.Search(e => e.Names, "Test").ToList();
Assert.True(documentQuery.Any());
}
using (var session = store.OpenSession())
{
var documentQuery = session.Advanced.DocumentQuery<Person_ForSearch.Result, RawRqlIndex>()
.Search(e => e.Names, "Test").ToList();
Assert.True(documentQuery.Any());
}
using (var session = store.OpenSession())
{
var documentQuery = session.Advanced.DocumentQuery<Person_ForSearch.Result, JavaScriptIndex>()
.Search(e => e.Names, "Test").ToList();
Assert.True(documentQuery.Any());
}
}
}
public class Person_ForSearch : AbstractIndexCreationTask<AnotherNameSpace.Person, Person_ForSearch.Result>
{
public class Result : Person
{
public string Query { get; set; }
public List<string> Names { get; set; }
}
public Person_ForSearch()
{
Map = persons => from person in persons
select new
{
person.Name,
Names = person.DocumentReferences.Select(e => e.Name),
Query = AsJson(person).Select(x => x.Value),
};
Index(i => i.Query, FieldIndexing.Search);
Index(i => i.Names, FieldIndexing.Search);
Store(i => i.Names, FieldStorage.Yes);
}
}
private class RawRqlIndex : AbstractIndexCreationTask
{
public override IndexDefinition CreateIndexDefinition()
{
return new IndexDefinition
{
Maps = new HashSet<string>
{
@"
from person in docs.People select new
{
Name = person.Name,
Names = person.DocumentReferences.Select(e => e.Name),
Query = AsJson(person).Select(x => x.Value)
}"
}
};
}
}
private class JavaScriptIndex : AbstractJavaScriptIndexCreationTask
{
public override IndexDefinition CreateIndexDefinition()
{
return new IndexDefinition
{
Maps = new HashSet<string>
{
@"
map('People', function (p) {
return {
Name: p.Name,
Names: p.DocumentReferences.map(r => r.Name),
Query: Object.values(p)
}
})"
}
};
}
}
public class Person
{
internal List<IRef> DocumentReferences { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public List<PersonRef> Family { get; set; }
}
public class PersonRef : IRef
{
public string RefId { get; set; }
public string Name { get; set; }
}
public interface IRef
{
public string RefId { get; set; }
}
public class ContractResolver : IContractResolver
{
private readonly IContractResolver _contractResolver;
public ContractResolver(IContractResolver contractResolver)
{
_contractResolver = contractResolver;
}
public JsonContract ResolveContract(Type type)
{
var contract = _contractResolver.ResolveContract(type);
contract.IsReference = contract.IsReference ?? false;
if (type.IsAssignableTo<IRef>())
{
contract.IsReference = true;
}
return contract;
}
}
public class IdReferenceResolver : IReferenceResolver
{
private readonly IReferenceResolver _referenceResolver;
public IdReferenceResolver(IReferenceResolver referenceResolver)
{
_referenceResolver = referenceResolver;
}
public object ResolveReference(object context, string reference)
{
return _referenceResolver.ResolveReference(context, reference);
}
public string GetReference(object context, object value)
{
if (value is IRef)
{
var r = value as IRef;
// We need the original as the default implementation will see them as different and throw an exception!
var original = _referenceResolver.ResolveReference(context, r.RefId.ToString());
if (original == null)
{
_referenceResolver.AddReference(context, r.RefId.ToString(), value);
}
return _referenceResolver.GetReference(context, original ?? value);
}
return _referenceResolver.GetReference(context, value);
}
public bool IsReferenced(object context, object value)
{
if (value is IRef)
{
var r = value as IRef;
var original = _referenceResolver.ResolveReference(context, r.RefId.ToString());
return original != null;
}
return _referenceResolver.IsReferenced(context, value);
}
public void AddReference(object context, string reference, object value)
{
_referenceResolver.AddReference(context, reference, value);
}
}
}
}
namespace AnotherNameSpace
{
public class Person
{
internal List<TestClass.PersonRef> DocumentReferences { get; set; }
public string Id { get; set; }
public string Name { get; set; }
}
}
Best regards,
Igal
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/e6b32084-3639-4da0-8685-d55836854aaan%40googlegroups.com.