Skip to content

Commit 52376fd

Browse files
Ihar YakimushIhar Yakimush
authored andcommitted
support score pseudo field
1 parent 871a2bd commit 52376fd

File tree

6 files changed

+143
-3
lines changed

6 files changed

+143
-3
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,33 @@ IQueryable<Product> solrLinq = solr.AsQueryable(setup =>
102102
// cat:(qwe)
103103
Product[] result = solrLinq.Where(p => p.Categories.Any(s => s == "qwe")).ToArray();
104104
```
105+
### Select
106+
- Anonymous type with fields, pseudo field, functions and transformers
107+
```
108+
var result = solrLinq.Select(p =>
109+
new {
110+
p.Id,
111+
p.Categories,
112+
Qwe = Math.Pow(2,2), // function
113+
ValStr = SolrExpr.Transformers.Value("qwe"), // value transformer
114+
Score= SolrExpr.Fields.Score() // score pseudo field
115+
}).OrderBy(arg => arg.Score).ToSolrQueryResults();
116+
```
117+
### Select
118+
- Existing type by member initialization
119+
```
120+
var result = solrLinq.Select(p => new Product2 {Id = p.Id, Price = p.Price, Categories = p.Categories, Qwe = Math.Pow(2, 2)}).ToArray();
121+
```
122+
- Combine Select with other methods
123+
```
124+
var result = solrLinq
125+
.Where(p => p.Id != null)
126+
.Select(p => new {p.Id, p.Price, p.Categories, Qwe = Math.Pow(2, 2)})
127+
.Where(arg => arg.Categories.Any(s => s == "electronics"))
128+
.OrderBy(arg => arg.Id).ThenBy(arg=>arg.Qwe)
129+
.Select(arg => new {arg.Id})
130+
.FirstOrDefault(arg2 => arg2.Id != null);
131+
```
105132
### Paging
106133
- Top
107134
- Skip

SolrNet.Linq.IntegrationTests/SelectTests.cs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,45 @@ public void AnonymousClass()
4040
Assert.True(t1.Price > 0);
4141
}
4242

43+
[Fact]
44+
public void AnonymousIdAndScore()
45+
{
46+
var t1 = Product.SolrOperations.Value.AsQueryable(lo => lo.SetupQueryOptions = qo =>
47+
{
48+
Assert.Equal("Score:score", qo.Fields.ElementAt(0));
49+
Assert.Equal("Id:id", qo.Fields.ElementAt(1));
50+
})
51+
.Select(p => new { p.Id, Score= SolrExpr.Fields.Score()})
52+
.OrderBy(arg => arg.Score)
53+
.FirstOrDefault();
54+
55+
Assert.NotNull(t1);
56+
Assert.NotNull(t1.Id);
57+
Assert.Equal(1, t1.Score);
58+
}
59+
60+
[Fact]
61+
public void AnonymousOrderByProduct()
62+
{
63+
var t1 = Product.SolrOperations.Value.AsQueryable(lo => lo.SetupQueryOptions = qo =>
64+
{
65+
Assert.Equal("Qwe:pow(2,2)", qo.Fields.ElementAt(0));
66+
Assert.Equal("Id:id", qo.Fields.ElementAt(1));
67+
Assert.Equal("Price:price", qo.Fields.ElementAt(2));
68+
Assert.Equal("Categories:cat", qo.Fields.ElementAt(3));
69+
}).Where(p => p.Id != null)
70+
.Select(p => new { p.Id, p.Price, p.Categories, Qwe = Math.Pow(2, 2) })
71+
.Where(arg => arg.Categories.Any(s => s == "electronics"))
72+
.OrderBy(arg => arg.Id).ThenBy(arg=>arg.Qwe)
73+
.FirstOrDefault();
74+
75+
Assert.NotNull(t1);
76+
Assert.NotNull(t1.Id);
77+
Assert.Equal(4, t1.Qwe);
78+
Assert.True(t1.Categories.Count > 0);
79+
Assert.True(t1.Price > 0);
80+
}
81+
4382
[Fact]
4483
public void AnonymousClassSolrResult()
4584
{
@@ -67,7 +106,7 @@ public void MultipleSelects()
67106
}).Where(p => p.Id != null)
68107
.Select(p => new {p.Id, p.Price, p.Categories, Qwe = Math.Pow(2, 2)})
69108
.Where(arg => arg.Categories.Any(s => s == "electronics"))
70-
.OrderBy(arg => arg.Id)
109+
.OrderBy(arg => arg.Id).ThenBy(arg=>arg.Qwe)
71110
.Select(arg => new {arg.Id})
72111
.FirstOrDefault(arg2 => arg2.Id != null);
73112

@@ -87,14 +126,24 @@ public void Transformers()
87126
ValFloat = SolrExpr.Transformers.Value((float) 2),
88127
ValDouble = SolrExpr.Transformers.Value((double) 3),
89128
ValDate = SolrExpr.Transformers.Value(dateTime),
90-
})
129+
ExplNl = SolrExpr.Transformers.ExplainNl(),
130+
ExplText = SolrExpr.Transformers.ExplainText(),
131+
ExplHtml = SolrExpr.Transformers.ExplainHtml(),
132+
DocId = SolrExpr.Transformers.DocId()
133+
}).Skip(1)
91134
.First();
92135

93136
Assert.Equal("qwe", t1.ValStr);
94137
Assert.Equal(1, t1.ValInt);
95138
Assert.Equal(2f, t1.ValFloat);
96139
Assert.Equal(3d, t1.ValDouble);
97140
Assert.Equal(dateTime, t1.ValDate);
141+
142+
Assert.NotNull(t1.ExplText);
143+
Assert.NotNull(t1.ExplNl);
144+
Assert.NotNull(t1.ExplHtml);
145+
146+
Assert.Equal(1, t1.DocId);
98147
}
99148

100149
[Fact]

SolrNet.Linq/Expressions/MemberExpressionExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Linq.Expressions;
77
using System.Reflection;
8+
using System.Xml.Linq;
89
using SolrNet.Impl;
910
using SolrNet.Linq.Expressions.Context;
1011

@@ -34,7 +35,19 @@ public static class MemberExpressionExtensions
3435
{ nameof(SolrExpr.Transformers.Value) + typeof(float).Name ,(c,t) => $"[value v={c.Arguments[0].GetSolrMemberProduct(t)} t=float]" },
3536
{ nameof(SolrExpr.Transformers.Value) + typeof(double).Name ,(c,t) => $"[value v={c.Arguments[0].GetSolrMemberProduct(t)} t=double]" },
3637
{ nameof(SolrExpr.Transformers.Value) + typeof(DateTime).Name ,(c,t) => $"[value v={c.Arguments[0].GetSolrMemberProduct(t)} t=date]" },
38+
39+
{ nameof(SolrExpr.Transformers.ExplainHtml) + typeof(string).Name ,(c,t) => "[explain style=html]" },
40+
{ nameof(SolrExpr.Transformers.ExplainNl) + typeof(XElement).Name ,(c,t) => "[explain style=nl]" },
41+
{ nameof(SolrExpr.Transformers.ExplainText) + typeof(string).Name ,(c,t) => "[explain style=text]" },
42+
43+
{ nameof(SolrExpr.Transformers.DocId) + typeof(int).Name ,(c,t) => "[docid]" },
44+
3745
};
46+
private static readonly Dictionary<string, Func<MethodCallExpression, MemberContext, string>> FieldsHelper = new Dictionary<string, Func<MethodCallExpression, MemberContext, string>> {
47+
{ nameof(SolrExpr.Fields.Score) ,(c,t) => "score" },
48+
49+
};
50+
3851

3952
internal static string GetSolrMemberProduct(this Expression exp, MemberContext context, bool disableFunctions = false)
4053
{
@@ -86,6 +99,14 @@ internal static string GetSolrMemberProduct(this Expression exp, MemberContext c
8699
return TransformersHelper[tkey].Invoke(call, context);
87100
}
88101
}
102+
103+
if (call.Method.DeclaringType == typeof(SolrExpr.Fields))
104+
{
105+
if (FieldsHelper.ContainsKey(call.Method.Name))
106+
{
107+
return FieldsHelper[call.Method.Name].Invoke(call, context);
108+
}
109+
}
89110
}
90111
}
91112

SolrNet.Linq/Impl/SelectResponseParser.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,21 @@ public T ParseDocument(XElement node)
3838
object obj = p.ParameterType.IsValueType ? Activator.CreateInstance(p.ParameterType) : null;
3939
if (fields.ContainsKey(p.Name))
4040
{
41-
if (this.parser.CanHandleSolrType(fields[p.Name].Name.LocalName) &&
41+
if (p.ParameterType == typeof(XElement))
42+
{
43+
string text = fields[p.Name].ToString();
44+
try
45+
{
46+
47+
obj = XElement.Parse(text);
48+
}
49+
catch (Exception e)
50+
{
51+
throw new InvalidOperationException(
52+
$"Unable to set value for {p.Name}. Value {text} can't be parsed to XElement",e);
53+
}
54+
}
55+
else if (this.parser.CanHandleSolrType(fields[p.Name].Name.LocalName) &&
4256
this.parser.CanHandleType(p.ParameterType))
4357
{
4458
obj = this.parser.Parse(fields[p.Name], p.ParameterType);

SolrNet.Linq/SolrExpr.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Xml.Linq;
23
using SolrNet.Linq.Expressions;
34
using SolrNet.Linq.Expressions.Context;
45

@@ -11,6 +12,14 @@ private static T Throw<T>(T value)
1112
throw new InvalidOperationException("This method not intended to be invoked. Use it to build expressions only");
1213

1314
}
15+
16+
public static class Fields
17+
{
18+
public static double Score()
19+
{
20+
return Throw(0);
21+
}
22+
}
1423
public static class Transformers
1524
{
1625
public static string Value(string value)
@@ -37,6 +46,26 @@ public static DateTime Value(DateTime value)
3746
{
3847
return Throw(value);
3948
}
49+
50+
public static XElement ExplainNl()
51+
{
52+
return Throw<XElement>(null);
53+
}
54+
55+
public static string ExplainText()
56+
{
57+
return Throw(string.Empty);
58+
}
59+
60+
public static string ExplainHtml()
61+
{
62+
return Throw(string.Empty);
63+
}
64+
65+
public static int DocId()
66+
{
67+
return Throw(0);
68+
}
4069
}
4170
}
4271
}

0 commit comments

Comments
 (0)