Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow to set boost level over the entire document

  • Loading branch information...
commit ed71ef8e5e94558f9f1b43ba0010d082a435b757 1 parent 6af7f14
@ayende ayende authored
View
25 Raven.Database/Indexing/MapReduceIndex.cs
@@ -16,6 +16,7 @@
using Lucene.Net.Store;
using Newtonsoft.Json;
using Raven.Abstractions;
+using Raven.Abstractions.Data;
using Raven.Abstractions.Extensions;
using Raven.Abstractions.Indexing;
using Raven.Abstractions.Linq;
@@ -277,17 +278,19 @@ public override void Remove(string[] keys, WorkContext context)
PropertyDescriptorCollection properties = null;
var anonymousObjectToLuceneDocumentConverter = new AnonymousObjectToLuceneDocumentConverter(indexDefinition);
var luceneDoc = new Document();
- var reduceKeyField = new Field(Abstractions.Data.Constants.ReduceKeyFieldName, "dummy",
+ var reduceKeyField = new Field(Constants.ReduceKeyFieldName, "dummy",
Field.Store.NO, Field.Index.NOT_ANALYZED_NO_NORMS);
foreach (var doc in RobustEnumerationReduce(mappedResults, viewGenerator.ReduceDefinition, actions, context))
{
count++;
- var fields = GetFields(anonymousObjectToLuceneDocumentConverter, doc, ref properties).ToList();
+ float boost;
+ var fields = GetFields(anonymousObjectToLuceneDocumentConverter, doc, ref properties, out boost).ToList();
string reduceKeyAsString = ExtractReduceKey(viewGenerator, doc);
reduceKeyField.SetValue(reduceKeyAsString.ToLowerInvariant());
luceneDoc.GetFields().Clear();
+ luceneDoc.SetBoost(boost);
luceneDoc.Add(reduceKeyField);
foreach (var field in fields)
{
@@ -342,8 +345,15 @@ private string ExtractReduceKey(AbstractViewGenerator viewGenerator, object doc)
}
}
- private IEnumerable<AbstractField> GetFields(AnonymousObjectToLuceneDocumentConverter anonymousObjectToLuceneDocumentConverter, object doc, ref PropertyDescriptorCollection properties)
+ private IEnumerable<AbstractField> GetFields(AnonymousObjectToLuceneDocumentConverter anonymousObjectToLuceneDocumentConverter, object doc, ref PropertyDescriptorCollection properties, out float boost)
{
+ boost = 1;
+ var boostedValue = doc as BoostedValue;
+ if (boostedValue != null)
+ {
+ doc = boostedValue.Value;
+ boost = boostedValue.Boost;
+ }
IEnumerable<AbstractField> fields;
if (doc is IDynamicJsonObject)
{
@@ -355,6 +365,15 @@ private IEnumerable<AbstractField> GetFields(AnonymousObjectToLuceneDocumentConv
properties = properties ?? TypeDescriptor.GetProperties(doc);
fields = anonymousObjectToLuceneDocumentConverter.Index(doc, properties, indexDefinition, Field.Store.YES);
}
+ if (Math.Abs(boost - 1) > float.Epsilon)
+ {
+ var abstractFields = fields.ToList();
+ foreach (var abstractField in abstractFields)
+ {
+ abstractField.SetOmitNorms(false);
+ }
+ return abstractFields;
+ }
return fields;
}
}
View
38 Raven.Database/Indexing/SimpleIndex.cs
@@ -76,16 +76,14 @@ public override void IndexDocuments(AbstractViewGenerator viewGenerator, IEnumer
{
count++;
- IndexingResult indexingResult;
- if (doc is DynamicJsonObject)
- indexingResult = ExtractIndexDataFromDocument(anonymousObjectToLuceneDocumentConverter, (DynamicJsonObject)doc);
- else
- indexingResult = ExtractIndexDataFromDocument(anonymousObjectToLuceneDocumentConverter, properties, doc);
+ float boost;
+ var indexingResult = GetIndexingResult(ref properties, doc, anonymousObjectToLuceneDocumentConverter, out boost);
if (indexingResult.NewDocId != null && indexingResult.ShouldSkip == false)
{
madeChanges = true;
luceneDoc.GetFields().Clear();
+ luceneDoc.SetBoost(boost);
documentIdField.SetValue(indexingResult.NewDocId.ToLowerInvariant());
luceneDoc.Add(documentIdField);
foreach (var field in indexingResult.Fields)
@@ -123,6 +121,34 @@ public override void IndexDocuments(AbstractViewGenerator viewGenerator, IEnumer
logIndexing.Debug("Indexed {0} documents for {1}", count, name);
}
+ private IndexingResult GetIndexingResult(ref PropertyDescriptorCollection properties, object doc, AnonymousObjectToLuceneDocumentConverter anonymousObjectToLuceneDocumentConverter, out float boost)
+ {
+ boost = 1;
+
+ var boostedValue = doc as BoostedValue;
+ if (boostedValue != null)
+ {
+ doc = boostedValue.Value;
+ boost = boostedValue.Boost;
+ }
+
+ IndexingResult indexingResult;
+ if (doc is DynamicJsonObject)
+ indexingResult = ExtractIndexDataFromDocument(anonymousObjectToLuceneDocumentConverter, (DynamicJsonObject) doc);
+ else
+ indexingResult = ExtractIndexDataFromDocument(anonymousObjectToLuceneDocumentConverter, ref properties, doc);
+
+ if (Math.Abs(boost - 1) > float.Epsilon)
+ {
+ foreach (var abstractField in indexingResult.Fields)
+ {
+ abstractField.SetOmitNorms(false);
+ }
+ }
+
+ return indexingResult;
+ }
+
private class IndexingResult
{
public string NewDocId;
@@ -142,7 +168,7 @@ private IndexingResult ExtractIndexDataFromDocument(AnonymousObjectToLuceneDocum
};
}
- private IndexingResult ExtractIndexDataFromDocument(AnonymousObjectToLuceneDocumentConverter anonymousObjectToLuceneDocumentConverter, PropertyDescriptorCollection properties, object doc)
+ private IndexingResult ExtractIndexDataFromDocument(AnonymousObjectToLuceneDocumentConverter anonymousObjectToLuceneDocumentConverter, ref PropertyDescriptorCollection properties, object doc)
{
if (properties == null)
{
View
4 Raven.Database/Linq/Ast/CaptureQueryParameterNamesVisitor.cs
@@ -49,8 +49,8 @@ public override object VisitQueryExpressionLetClause(QueryExpressionLetClause qu
}
private void ProcessQuery(Expression queryExpressionSelectClause)
- {
- var objectCreateExpression = queryExpressionSelectClause as ObjectCreateExpression;
+ {
+ var objectCreateExpression = QueryParsingUtils.GetAnonymousCreateExpression(queryExpressionSelectClause) as ObjectCreateExpression;
if (objectCreateExpression == null ||
objectCreateExpression.IsAnonymousType == false)
return;
View
6 Raven.Database/Linq/Ast/CaptureSelectNewFieldNamesVisitor.cs
@@ -55,9 +55,9 @@ public override object VisitInvocationExpression(InvocationExpression invocation
private bool queryProcessed;
- private void ProcessQuery(Expression queryExpressionSelectClause)
- {
- var objectCreateExpression = queryExpressionSelectClause as ObjectCreateExpression;
+ private void ProcessQuery(Expression queryExpressionSelectClause)
+ {
+ var objectCreateExpression = QueryParsingUtils.GetAnonymousCreateExpression(queryExpressionSelectClause) as ObjectCreateExpression;
if (objectCreateExpression == null ||
objectCreateExpression.IsAnonymousType == false)
return;
View
8 Raven.Database/Linq/DynamicViewCompiler.cs
@@ -353,10 +353,10 @@ public override object VisitLambdaExpression(LambdaExpression lambdaExpression,
private void AddDocumentIdFieldToLambdaIfCreatingNewObject(LambdaExpression lambdaExpression)
{
- if (lambdaExpression.ExpressionBody is ObjectCreateExpression == false)
- return;
- var objectCreateExpression = ((ObjectCreateExpression)lambdaExpression.ExpressionBody);
- if (objectCreateExpression.IsAnonymousType == false)
+
+ var objectCreateExpression = QueryParsingUtils.GetAnonymousCreateExpression(lambdaExpression.ExpressionBody) as ObjectCreateExpression;
+
+ if (objectCreateExpression == null || objectCreateExpression.IsAnonymousType == false)
return;
var objectInitializer = objectCreateExpression.ObjectInitializer;
View
28 Raven.Database/Linq/QueryParsingUtils.cs
@@ -144,7 +144,9 @@ public static VariableDeclaration GetVariableDeclarationForLinqMethods(string qu
variable.AcceptVisitor(new TransformNullCoalasingOperatorTransformer(), null);
variable.AcceptVisitor(new DynamicExtensionMethodsTranslator(), null);
- var objectCreateExpression = lambdaExpression.ExpressionBody as ObjectCreateExpression;
+ var expressionBody = GetAnonymousCreateExpression(lambdaExpression.ExpressionBody);
+
+ var objectCreateExpression = expressionBody as ObjectCreateExpression;
if (objectCreateExpression == null && requiresSelectNewAnonymousType)
throw new InvalidOperationException("Variable initializer select must have a lambda expression with an object create expression");
@@ -154,6 +156,30 @@ public static VariableDeclaration GetVariableDeclarationForLinqMethods(string qu
return variable;
}
+ public static Expression GetAnonymousCreateExpression(Expression expression)
+ {
+ var invocationExpression = expression as InvocationExpression;
+
+ if (invocationExpression == null)
+ return expression;
+ var memberReferenceExpression = invocationExpression.TargetObject as MemberReferenceExpression;
+ if (memberReferenceExpression == null)
+ return expression;
+ var typeReference = memberReferenceExpression.TargetObject as TypeReferenceExpression;
+ if (typeReference == null)
+ return expression;
+
+ if (typeReference.TypeReference.Type != "Raven.Database.Linq.PrivateExtensions.DynamicExtensionMethods")
+ return expression;
+
+ switch (memberReferenceExpression.MemberName)
+ {
+ case "Boost":
+ return invocationExpression.Arguments[0];
+ }
+ return expression;
+ }
+
public static LambdaExpression AsLambdaExpression(this Expression expression)
{
var lambdaExpression = expression as LambdaExpression;
View
62 Raven.Tests/Indexes/BoostingDuringIndexing.cs
@@ -1,6 +1,7 @@
using System.Linq;
using Raven.Client.Indexes;
using Raven.Client.Linq.Indexing;
+using Raven.Client.Linq;
using Xunit;
namespace Raven.Tests.Indexes
@@ -13,6 +14,11 @@ public class User
public string LastName { get; set; }
}
+ public class Account
+ {
+ public string Name { get; set; }
+ }
+
public class UsersByName : AbstractIndexCreationTask<User>
{
public UsersByName()
@@ -26,6 +32,62 @@ select new
}
}
+ public class UsersAndAccounts : AbstractMultiMapIndexCreationTask<UsersAndAccounts.Result>
+ {
+ public class Result
+ {
+ public string Name { get; set; }
+ }
+
+ public UsersAndAccounts()
+ {
+ AddMap<User>(users =>
+ from user in users
+ select new {Name = user.FirstName}
+ );
+ AddMap<Account>(accounts =>
+ from account in accounts
+ select new {account.Name}.Boost(3)
+ );
+ }
+ }
+
+ [Fact]
+ public void CanBoostFullDocument()
+ {
+ using (var store = NewDocumentStore())
+ {
+ new UsersAndAccounts().Execute(store);
+
+ using (var session = store.OpenSession())
+ {
+ session.Store(new User
+ {
+ FirstName = "Oren",
+ });
+
+ session.Store(new Account()
+ {
+ Name = "Oren",
+ });
+ session.SaveChanges();
+ }
+
+ using (var session = store.OpenSession())
+ {
+ var results = session.Query<UsersAndAccounts.Result, UsersAndAccounts>()
+ .Customize(x => x.WaitForNonStaleResults())
+ .Where(x => x.Name == "Oren")
+ .As<object>()
+ .ToList();
+
+ Assert.Equal(2, results.Count);
+ Assert.IsType<Account>(results[0]);
+ Assert.IsType<User>(results[1]);
+ }
+ }
+ }
+
[Fact]
public void CanGetBoostedValues()
{
Please sign in to comment.
Something went wrong with that request. Please try again.