Skip to content

Commit a88caa7

Browse files
committed
First pass at term and suggest feature
Seems to work pretty well in a few scenarios that I tested, but still needs some good error handling, unit and integration tests, etc.
1 parent d21b231 commit a88caa7

13 files changed

+505
-37
lines changed

src/Nest/DSL/SearchDescriptor.cs

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ public abstract class SearchDescriptorBase
3131
public class SearchDescriptor<T> : SearchDescriptorBase where T : class
3232
{
3333
private readonly TypeNameResolver typeNameResolver;
34-
34+
3535
public SearchDescriptor()
3636
{
3737
this.typeNameResolver = new TypeNameResolver();
3838
}
3939

40-
40+
4141
internal override Type _ClrType { get { return typeof(T); } }
4242
internal Func<dynamic, Hit<dynamic>, Type> _ConcreteTypeSelector;
4343

@@ -71,7 +71,7 @@ public SearchDescriptor<T> Index(string index)
7171
public SearchDescriptor<T> Types(IEnumerable<string> types)
7272
{
7373
types.ThrowIfEmpty("types");
74-
this._Types = types.Select(s=>(TypeNameMarker)s);
74+
this._Types = types.Select(s => (TypeNameMarker)s);
7575
return this;
7676
}
7777
/// <summary>
@@ -91,7 +91,7 @@ public SearchDescriptor<T> Types(IEnumerable<Type> types)
9191
types.ThrowIfEmpty("types");
9292
this._Types = types.Select(s => (TypeNameMarker)s);
9393
return this;
94-
94+
9595
}
9696
/// <summary>
9797
/// The types to execute the search on. Defaults to the inferred typename of T
@@ -200,6 +200,9 @@ public SearchDescriptor<T> Strict(bool strict = true)
200200
[JsonProperty(PropertyName = "facets")]
201201
internal IDictionary<string, FacetDescriptorsBucket<T>> _Facets { get; set; }
202202

203+
[JsonProperty(PropertyName = "suggest")]
204+
internal IDictionary<string, SuggestDescriptorBucket<T>> _Suggest { get; set; }
205+
203206
[JsonProperty(PropertyName = "query")]
204207
internal RawOrQueryDescriptor<T> _QueryOrRaw
205208
{
@@ -246,10 +249,10 @@ internal RawOrFilterDescriptor<T> _FilterOrRaw
246249
internal IList<string> _Fields { get; set; }
247250

248251
[JsonProperty(PropertyName = "script_fields")]
249-
internal FluentDictionary<string, ScriptFilterDescriptor> _ScriptFields { get; set; }
252+
internal FluentDictionary<string, ScriptFilterDescriptor> _ScriptFields { get; set; }
250253

251-
[JsonProperty(PropertyName = "partial_fields")]
252-
internal Dictionary<string, PartialFieldDescriptor<T>> _PartialFields { get; set; }
254+
[JsonProperty(PropertyName = "partial_fields")]
255+
internal Dictionary<string, PartialFieldDescriptor<T>> _PartialFields { get; set; }
253256

254257
/// <summary>
255258
/// The number of hits to return. Defaults to 10. When using scroll search type
@@ -440,30 +443,30 @@ public SearchDescriptor<T> ScriptFields(
440443
return this;
441444
}
442445

443-
public SearchDescriptor<T> PartialFields(params Action<PartialFieldDescriptor<T>>[] partialFieldDescriptor)
444-
{
445-
if (this._PartialFields == null)
446-
this._PartialFields = new Dictionary<string, PartialFieldDescriptor<T>>();
446+
public SearchDescriptor<T> PartialFields(params Action<PartialFieldDescriptor<T>>[] partialFieldDescriptor)
447+
{
448+
if (this._PartialFields == null)
449+
this._PartialFields = new Dictionary<string, PartialFieldDescriptor<T>>();
447450

448-
var descriptors = new List<PartialFieldDescriptor<T>>();
451+
var descriptors = new List<PartialFieldDescriptor<T>>();
449452

450-
foreach (var selector in partialFieldDescriptor)
451-
{
452-
var filter = new PartialFieldDescriptor<T>();
453-
selector(filter);
454-
descriptors.Add(filter);
455-
}
453+
foreach (var selector in partialFieldDescriptor)
454+
{
455+
var filter = new PartialFieldDescriptor<T>();
456+
selector(filter);
457+
descriptors.Add(filter);
458+
}
456459

457-
foreach (var d in descriptors)
458-
{
459-
var key = d._Field;
460-
if (string.IsNullOrEmpty(key))
461-
throw new DslException("Could not infer key for highlight field descriptor");
460+
foreach (var d in descriptors)
461+
{
462+
var key = d._Field;
463+
if (string.IsNullOrEmpty(key))
464+
throw new DslException("Could not infer key for highlight field descriptor");
462465

463-
this._PartialFields.Add(key, d);
464-
}
465-
return this;
466-
}
466+
this._PartialFields.Add(key, d);
467+
}
468+
return this;
469+
}
467470

468471
/// <summary>
469472
/// <para>Allows to add one or more sort on specific fields. Each sort can be reversed as well.
@@ -836,6 +839,32 @@ public SearchDescriptor<T> FacetFilter(string name, Func<FilterDescriptor<T>, Ba
836839
return this;
837840
}
838841

842+
public SearchDescriptor<T> TermSuggest(string name, Func<TermSuggestDescriptor<T>, TermSuggestDescriptor<T>> suggest)
843+
{
844+
name.ThrowIfNullOrEmpty("name");
845+
suggest.ThrowIfNull("suggest");
846+
if (this._Suggest == null)
847+
this._Suggest = new Dictionary<string, SuggestDescriptorBucket<T>>();
848+
TermSuggestDescriptor<T> desc = new TermSuggestDescriptor<T>();
849+
TermSuggestDescriptor<T> item = suggest(desc);
850+
SuggestDescriptorBucket<T> bucket = new SuggestDescriptorBucket<T> { _Text = item._Text, TermSuggest = item };
851+
this._Suggest.Add(name, bucket);
852+
return this;
853+
}
854+
855+
public SearchDescriptor<T> PhraseSuggest(string name, Func<PhraseSuggestDescriptor<T>, PhraseSuggestDescriptor<T>> suggest)
856+
{
857+
name.ThrowIfNullOrEmpty("name");
858+
suggest.ThrowIfNull("suggest");
859+
if (this._Suggest == null)
860+
this._Suggest = new Dictionary<string, SuggestDescriptorBucket<T>>();
861+
PhraseSuggestDescriptor<T> desc = new PhraseSuggestDescriptor<T>();
862+
PhraseSuggestDescriptor<T> item = suggest(desc);
863+
SuggestDescriptorBucket<T> bucket = new SuggestDescriptorBucket<T> { _Text = item._Text, PhraseSuggest = item };
864+
this._Suggest.Add(name, bucket);
865+
return this;
866+
}
867+
839868
/// <summary>
840869
/// Describe the query to perform using a query descriptor lambda
841870
/// </summary>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Nest
4+
{
5+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
6+
public abstract class BaseSuggestDescriptor<T> : ISuggestDescriptor<T> where T : class
7+
{
8+
internal string _Text { get; set; }
9+
10+
[JsonProperty(PropertyName = "field")]
11+
internal string _Field { get; set; }
12+
13+
[JsonProperty(PropertyName = "analyzer")]
14+
internal string _Analyzer { get; set; }
15+
16+
[JsonProperty(PropertyName = "size")]
17+
internal int? _Size { get; set; }
18+
19+
[JsonProperty(PropertyName = "shard_size")]
20+
internal int? _ShardSize { get; set; }
21+
}
22+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
using System;
2+
using System.Linq.Expressions;
3+
using Newtonsoft.Json;
4+
using Nest.Resolvers;
5+
6+
namespace Nest
7+
{
8+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
9+
public class DirectGeneratorDescriptor<T> where T : class
10+
{
11+
[JsonProperty(PropertyName = "field")]
12+
internal string _Field { get; set; }
13+
14+
[JsonProperty(PropertyName = "size")]
15+
internal int? _Size { get; set; }
16+
17+
[JsonProperty(PropertyName = "prefix_len")]
18+
internal int? _PrefixLen { get; set; }
19+
20+
[JsonProperty(PropertyName = "suggest_mode")]
21+
internal string _SuggestMode { get; set; }
22+
23+
[JsonProperty(PropertyName = "min_word_len")]
24+
internal int? _MinWordLen { get; set; }
25+
26+
[JsonProperty(PropertyName = "max_edits")]
27+
internal int? _MaxEdits { get; set; }
28+
29+
[JsonProperty(PropertyName = "max_inspections")]
30+
internal decimal? _MaxInspections { get; set; }
31+
32+
[JsonProperty(PropertyName = "min_doc_freq")]
33+
internal decimal? _MinDocFrequency { get; set; }
34+
35+
[JsonProperty(PropertyName = "max_term_freq")]
36+
internal decimal? _MaxTermFrequency { get; set; }
37+
38+
[JsonProperty(PropertyName = "pre_filter")]
39+
internal string _PreFilter { get; set; }
40+
41+
[JsonProperty(PropertyName = "post_filter")]
42+
internal string _PostFilter { get; set; }
43+
44+
public DirectGeneratorDescriptor<T> OnField(string field)
45+
{
46+
this._Field = field;
47+
return this;
48+
}
49+
50+
public DirectGeneratorDescriptor<T> OnField(Expression<Func<T, object>> objectPath)
51+
{
52+
var fieldName = new PropertyNameResolver().Resolve(objectPath);
53+
return this.OnField(fieldName);
54+
}
55+
56+
public DirectGeneratorDescriptor<T> Size(int size)
57+
{
58+
this._Size = size;
59+
return this;
60+
}
61+
62+
public DirectGeneratorDescriptor<T> SuggestMode(SuggestMode mode)
63+
{
64+
this._SuggestMode = Enum.GetName(typeof(SuggestMode), mode).ToLower();
65+
return this;
66+
}
67+
68+
public DirectGeneratorDescriptor<T> MinWordLength(int length)
69+
{
70+
this._MinWordLen = length;
71+
return this;
72+
}
73+
74+
public DirectGeneratorDescriptor<T> PrefixLength(int length)
75+
{
76+
this._PrefixLen = length;
77+
return this;
78+
}
79+
80+
public DirectGeneratorDescriptor<T> MaxEdits(int maxEdits)
81+
{
82+
this._MaxEdits = maxEdits;
83+
return this;
84+
}
85+
86+
public DirectGeneratorDescriptor<T> MaxInspections(decimal maxInspections)
87+
{
88+
this._MaxInspections = maxInspections;
89+
return this;
90+
}
91+
92+
public DirectGeneratorDescriptor<T> MinDocFrequency(decimal frequency)
93+
{
94+
this._MinDocFrequency = frequency;
95+
return this;
96+
}
97+
98+
public DirectGeneratorDescriptor<T> MaxTermFrequency(decimal frequency)
99+
{
100+
this._MaxTermFrequency = frequency;
101+
return this;
102+
}
103+
104+
public DirectGeneratorDescriptor<T> PreFilter(string analyzer)
105+
{
106+
this._PreFilter = analyzer;
107+
return this;
108+
}
109+
110+
public DirectGeneratorDescriptor<T> PostFilter(string analyzer)
111+
{
112+
this._PostFilter = analyzer;
113+
return this;
114+
}
115+
116+
}
117+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Nest
2+
{
3+
public interface ISuggestDescriptor<out T> : ISuggestDescriptor
4+
{
5+
6+
}
7+
public interface ISuggestDescriptor
8+
{
9+
}
10+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Linq.Expressions;
5+
using Newtonsoft.Json;
6+
using Nest.Resolvers;
7+
8+
namespace Nest
9+
{
10+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
11+
public class PhraseSuggestDescriptor<T> : BaseSuggestDescriptor<T> where T : class
12+
{
13+
[JsonProperty(PropertyName = "gram_size")]
14+
internal int? _GramSize { get; set; }
15+
16+
[JsonProperty(PropertyName = "real_word_error_likelihood")]
17+
internal decimal? _RealWordErrorLikelyhood { get; set; }
18+
19+
[JsonProperty(PropertyName = "confidence")]
20+
internal decimal? _Confidence { get; set; }
21+
22+
[JsonProperty(PropertyName = "max_errors")]
23+
internal decimal? _MaxErrors { get; set; }
24+
25+
[JsonProperty(PropertyName = "separator")]
26+
internal char? _Separator { get; set; }
27+
28+
[JsonProperty(PropertyName = "direct_generator")]
29+
internal DirectGeneratorDescriptor<T>[] _DirectGenerator { get; set; }
30+
31+
public PhraseSuggestDescriptor<T> Text(string text)
32+
{
33+
this._Text = text;
34+
return this;
35+
}
36+
37+
public PhraseSuggestDescriptor<T> OnField(string field)
38+
{
39+
this._Field = field;
40+
return this;
41+
}
42+
43+
public PhraseSuggestDescriptor<T> OnField(Expression<Func<T, object>> objectPath)
44+
{
45+
var fieldName = new PropertyNameResolver().Resolve(objectPath);
46+
return this.OnField(fieldName);
47+
}
48+
49+
public PhraseSuggestDescriptor<T> Analyzer(string analyzer)
50+
{
51+
this._Analyzer = analyzer;
52+
return this;
53+
}
54+
55+
public PhraseSuggestDescriptor<T> Size(int size)
56+
{
57+
this._Size = size;
58+
return this;
59+
}
60+
61+
public PhraseSuggestDescriptor<T> ShardSize(int size)
62+
{
63+
this._ShardSize = size;
64+
return this;
65+
}
66+
67+
public PhraseSuggestDescriptor<T> GramSize(int gramSize)
68+
{
69+
this._GramSize = gramSize;
70+
return this;
71+
}
72+
73+
public PhraseSuggestDescriptor<T> Confidence(decimal confidence)
74+
{
75+
this._Confidence = confidence;
76+
return this;
77+
}
78+
79+
public PhraseSuggestDescriptor<T> MaxErrors(decimal maxErrors)
80+
{
81+
this._MaxErrors = maxErrors;
82+
return this;
83+
}
84+
85+
public PhraseSuggestDescriptor<T> Separator(char separator)
86+
{
87+
this._Separator = separator;
88+
return this;
89+
}
90+
91+
public PhraseSuggestDescriptor<T> DirectGenerator(params Func<DirectGeneratorDescriptor<T>, DirectGeneratorDescriptor<T>>[] generators)
92+
{
93+
List<DirectGeneratorDescriptor<T>> gens = new List<DirectGeneratorDescriptor<T>>();
94+
foreach (var generator in generators)
95+
{
96+
DirectGeneratorDescriptor<T> gen = new DirectGeneratorDescriptor<T>();
97+
gen = generator(gen);
98+
gens.Add(gen);
99+
}
100+
this._DirectGenerator = gens.ToArray();
101+
return this;
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)