Skip to content

Commit 167399e

Browse files
committedAug 25, 2014
fix #894 add support for ids and docs in MoreLikeThisQuery
1 parent 043c81d commit 167399e

File tree

5 files changed

+244
-16
lines changed

5 files changed

+244
-16
lines changed
 

Diff for: ‎src/Nest/DSL/MultiGet/MultiGetOperationDescriptor.cs

+14
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ public MultiGetOperationDescriptor()
4848
Self.Type = Self.ClrType;
4949
}
5050

51+
/// <summary>
52+
/// when rest.action.multi.allow_explicit_index is set to false you can use this constructor to generate a multiget operation
53+
/// with no index and type set
54+
/// <pre>
55+
/// See also: https://github.com/elasticsearch/elasticsearch/issues/3636
56+
/// </pre>
57+
/// </summary>
58+
/// <param name="initializeEmpty"></param>
59+
public MultiGetOperationDescriptor(bool allowExplicitIndex) : this()
60+
{
61+
if (allowExplicitIndex) return;
62+
Self.Index = null;
63+
}
64+
5165
/// <summary>
5266
/// Manually set the index, default to the default index or the index set for the type on the connectionsettings.
5367
/// </summary>

Diff for: ‎src/Nest/DSL/Query/MoreLikeThisQueryDescriptor.cs

+86-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34
using System.Linq;
45
using Nest.Resolvers.Converters;
56
using Newtonsoft.Json;
@@ -49,6 +50,25 @@ public interface IMoreLikeThisQuery : IQuery
4950

5051
[JsonProperty(PropertyName = "analyzer")]
5152
string Analyzer { get; set; }
53+
54+
/// <summary>
55+
/// A list of document ids. This parameter is required if like_text is not specified.
56+
/// The texts are fetched from fields unless specified in each doc, and cannot be set to _all.
57+
/// <pre>Available from Elasticsearch 1.3.0</pre>
58+
/// </summary>
59+
[JsonProperty("ids")]
60+
IEnumerable<string> Ids { get; set; }
61+
62+
/// <summary>
63+
/// A list of documents following the same syntax as the Multi GET API. This parameter is required if like_text is not specified.
64+
/// The texts are fetched from fields unless specified in each doc, and cannot be set to _all.
65+
/// <pre>Available from Elasticsearch 1.3.0</pre>
66+
/// </summary>
67+
[JsonProperty("docs")]
68+
IEnumerable<IMultiGetOperation> Documents { get; set; }
69+
70+
[JsonProperty(PropertyName = "include")]
71+
bool? Include { get; set; }
5272
}
5373

5474

@@ -73,11 +93,15 @@ protected override void WrapInContainer(IQueryContainer container)
7393
public double? BoostTerms { get; set; }
7494
public double? Boost { get; set; }
7595
public string Analyzer { get; set; }
96+
public IEnumerable<string> Ids { get; set; }
97+
public IEnumerable<IMultiGetOperation> Documents { get; set; }
98+
public bool? Include { get; set; }
7699
}
77100

78-
79101
public class MoreLikeThisQueryDescriptor<T> : IMoreLikeThisQuery where T : class
80102
{
103+
private IMoreLikeThisQuery Self { get { return this; }}
104+
81105
IEnumerable<PropertyPathMarker> IMoreLikeThisQuery.Fields { get; set; }
82106

83107
string IMoreLikeThisQuery.LikeText { get; set; }
@@ -103,87 +127,133 @@ public class MoreLikeThisQueryDescriptor<T> : IMoreLikeThisQuery where T : class
103127
double? IMoreLikeThisQuery.Boost { get; set; }
104128

105129
string IMoreLikeThisQuery.Analyzer { get; set; }
130+
131+
IEnumerable<string> IMoreLikeThisQuery.Ids { get; set; }
132+
133+
IEnumerable<IMultiGetOperation> IMoreLikeThisQuery.Documents { get; set; }
134+
135+
bool? IMoreLikeThisQuery.Include { get; set; }
106136

107137
bool IQuery.IsConditionless
108138
{
109139
get
110140
{
111-
return ((IMoreLikeThisQuery)this).LikeText.IsNullOrEmpty();
141+
return this.Self.LikeText.IsNullOrEmpty();
112142
}
113143
}
114144

115145
public MoreLikeThisQueryDescriptor<T> OnFields(IEnumerable<string> fields)
116146
{
117-
((IMoreLikeThisQuery)this).Fields = fields.Select(f=>(PropertyPathMarker)f);
147+
this.Self.Fields = fields.Select(f=>(PropertyPathMarker)f);
118148
return this;
119149
}
120150
public MoreLikeThisQueryDescriptor<T> OnFields(
121151
params Expression<Func<T, object>>[] objectPaths)
122152
{
123-
((IMoreLikeThisQuery)this).Fields = objectPaths.Select(e=>(PropertyPathMarker)e);
153+
this.Self.Fields = objectPaths.Select(e=>(PropertyPathMarker)e);
124154
return this;
125155
}
126156
public MoreLikeThisQueryDescriptor<T> LikeText(string likeText)
127157
{
128-
((IMoreLikeThisQuery)this).LikeText = likeText;
158+
this.Self.LikeText = likeText;
129159
return this;
130160
}
131161
public MoreLikeThisQueryDescriptor<T> StopWords(IEnumerable<string> stopWords)
132162
{
133-
((IMoreLikeThisQuery)this).StopWords = stopWords;
163+
this.Self.StopWords = stopWords;
134164
return this;
135165
}
136166

137167
public MoreLikeThisQueryDescriptor<T> MaxQueryTerms(int maxQueryTerms)
138168
{
139-
((IMoreLikeThisQuery)this).MaxQueryTerms = maxQueryTerms;
169+
this.Self.MaxQueryTerms = maxQueryTerms;
140170
return this;
141171
}
142172
public MoreLikeThisQueryDescriptor<T> MinTermFrequency(int minTermFrequency)
143173
{
144-
((IMoreLikeThisQuery)this).MinTermFrequency = minTermFrequency;
174+
this.Self.MinTermFrequency = minTermFrequency;
145175
return this;
146176
}
147177
public MoreLikeThisQueryDescriptor<T> MinDocumentFrequency(int minDocumentFrequency)
148178
{
149-
((IMoreLikeThisQuery)this).MinDocumentFrequency = minDocumentFrequency;
179+
this.Self.MinDocumentFrequency = minDocumentFrequency;
150180
return this;
151181
}
152182
public MoreLikeThisQueryDescriptor<T> MaxDocumentFrequency(int maxDocumentFrequency)
153183
{
154-
((IMoreLikeThisQuery)this).MaxDocumentFrequency = maxDocumentFrequency;
184+
this.Self.MaxDocumentFrequency = maxDocumentFrequency;
155185
return this;
156186
}
157187
public MoreLikeThisQueryDescriptor<T> MinWordLength(int minWordLength)
158188
{
159-
((IMoreLikeThisQuery)this).MinWordLength = minWordLength;
189+
this.Self.MinWordLength = minWordLength;
160190
return this;
161191
}
162192
public MoreLikeThisQueryDescriptor<T> MaxWordLength(int maxWordLength)
163193
{
164-
((IMoreLikeThisQuery)this).MaxWordLength = maxWordLength;
194+
this.Self.MaxWordLength = maxWordLength;
165195
return this;
166196
}
167197
public MoreLikeThisQueryDescriptor<T> BoostTerms(double boostTerms)
168198
{
169-
((IMoreLikeThisQuery)this).BoostTerms = boostTerms;
199+
this.Self.BoostTerms = boostTerms;
170200
return this;
171201
}
172202
public MoreLikeThisQueryDescriptor<T> TermMatchPercentage(double termMatchPercentage)
173203
{
174-
((IMoreLikeThisQuery)this).TermMatchPercentage = termMatchPercentage;
204+
this.Self.TermMatchPercentage = termMatchPercentage;
175205
return this;
176206
}
177207
public MoreLikeThisQueryDescriptor<T> Boost(double boost)
178208
{
179-
((IMoreLikeThisQuery)this).Boost = boost;
209+
this.Self.Boost = boost;
180210
return this;
181211
}
182212
public MoreLikeThisQueryDescriptor<T> Analyzer(string analyzer)
183213
{
184-
((IMoreLikeThisQuery)this).Analyzer = analyzer;
214+
this.Self.Analyzer = analyzer;
215+
return this;
216+
}
217+
218+
public MoreLikeThisQueryDescriptor<T> Ids(IEnumerable<long> ids)
219+
{
220+
this.Self.Ids = ids.Select(i=>i.ToString(CultureInfo.InvariantCulture));
185221
return this;
186222
}
187223

224+
public MoreLikeThisQueryDescriptor<T> Ids(IEnumerable<string> ids)
225+
{
226+
this.Self.Ids = ids;
227+
return this;
228+
}
229+
230+
/// <summary>
231+
/// Specify multiple documents to suply the more like this like text
232+
/// </summary>
233+
public MoreLikeThisQueryDescriptor<T> Documents(Func<MoreLikeThisQueryDocumentsDescriptor<T>, MoreLikeThisQueryDocumentsDescriptor<T>> getDocumentsSelector)
234+
{
235+
getDocumentsSelector.ThrowIfNull("getDocumentsSelector");
236+
237+
var descriptor = getDocumentsSelector(new MoreLikeThisQueryDocumentsDescriptor<T>(true));
238+
descriptor.ThrowIfNull("descriptor");
239+
Self.Documents = descriptor.GetOperations;
240+
return this;
241+
}
242+
243+
/// <summary>
244+
/// Specify multiple documents to supply the more like this text, but do not generate index: and type: on the get operations.
245+
/// Useful if the node has rest.action.multi.allow_explicit_index set to false
246+
/// </summary>
247+
/// <param name="getDocumentsSelector"></param>
248+
/// <returns></returns>
249+
public MoreLikeThisQueryDescriptor<T> DocumentsExplicit(Func<MoreLikeThisQueryDocumentsDescriptor<T>, MoreLikeThisQueryDocumentsDescriptor<T>> getDocumentsSelector)
250+
{
251+
getDocumentsSelector.ThrowIfNull("getDocumentsSelector");
252+
253+
var descriptor = getDocumentsSelector(new MoreLikeThisQueryDocumentsDescriptor<T>(false));
254+
descriptor.ThrowIfNull("descriptor");
255+
Self.Documents = descriptor.GetOperations;
256+
return this;
257+
}
188258
}
189259
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
5+
namespace Nest
6+
{
7+
public class MoreLikeThisQueryDocumentsDescriptor<T> where T : class
8+
{
9+
private readonly bool _allowExplicitIndex;
10+
internal IList<IMultiGetOperation> GetOperations { get; set; }
11+
12+
public MoreLikeThisQueryDocumentsDescriptor(bool allowExplicitIndex = true)
13+
{
14+
_allowExplicitIndex = allowExplicitIndex;
15+
this.GetOperations = new List<IMultiGetOperation>();
16+
}
17+
18+
/// <summary>
19+
/// Describe a get operation for the mlt_query docs property
20+
/// </summary>
21+
public MoreLikeThisQueryDocumentsDescriptor<T> Get(long id, Func<MultiGetOperationDescriptor<T>, MultiGetOperationDescriptor<T>> getSelector = null)
22+
{
23+
return this.Get(id.ToString(CultureInfo.InvariantCulture), getSelector);
24+
}
25+
26+
/// <summary>
27+
/// Describe a get operation for the mlt_query docs property
28+
/// </summary>
29+
public MoreLikeThisQueryDocumentsDescriptor<T> Get(string id, Func<MultiGetOperationDescriptor<T>, MultiGetOperationDescriptor<T>> getSelector = null)
30+
{
31+
getSelector = getSelector ?? (s => s);
32+
var descriptor = getSelector(new MultiGetOperationDescriptor<T>(_allowExplicitIndex).Id(id));
33+
this.GetOperations.Add(descriptor);
34+
return this;
35+
}
36+
37+
/// <summary>
38+
/// Describe a get operation for the mlt_query docs property
39+
/// </summary>
40+
/// <typeparam name="TDocument">Use a different type to lookup</typeparam>
41+
public MoreLikeThisQueryDocumentsDescriptor<T> Get<TDocument>(long id, Func<MultiGetOperationDescriptor<TDocument>, MultiGetOperationDescriptor<TDocument>> getSelector = null)
42+
where TDocument : class
43+
{
44+
return this.Get<TDocument>(id.ToString(CultureInfo.InvariantCulture), getSelector);
45+
}
46+
47+
/// <summary>
48+
/// Describe a get operation for the mlt_query docs property
49+
/// </summary>
50+
/// <typeparam name="TDocument">Use a different type to lookup</typeparam>
51+
public MoreLikeThisQueryDocumentsDescriptor<T> Get<TDocument>(string id, Func<MultiGetOperationDescriptor<TDocument>, MultiGetOperationDescriptor<TDocument>> getSelector = null)
52+
where TDocument : class
53+
{
54+
getSelector = getSelector ?? (s => s);
55+
var descriptor = getSelector(new MultiGetOperationDescriptor<TDocument>(_allowExplicitIndex).Id(id));
56+
this.GetOperations.Add(descriptor);
57+
return this;
58+
59+
}
60+
}
61+
}

Diff for: ‎src/Nest/Nest.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@
170170
<Compile Include="DSL\MultiPercolateDescriptor.cs" />
171171
<Compile Include="DSL\Paths\IndexOptionalNamePathDescriptor.cs" />
172172
<Compile Include="DSL\Paths\IndicesOptionalTypesNamePathDecriptor.cs" />
173+
<Compile Include="DSL\Query\SubDescriptors\MoreLikeThisQueryDocumentsDescriptor.cs" />
173174
<Compile Include="DSL\Query\SpanMultiTermQueryDescriptor.cs" />
174175
<Compile Include="DSL\TypeExistsDescriptor.cs" />
175176
<Compile Include="DSL\Query\Functions\FieldValueFactorDescriptor.cs" />

Diff for: ‎src/Tests/Nest.Tests.Unit/Search/Query/Singles/MoreLikeThisQueryJson.cs

+82
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,88 @@ public void TestMoreLikeThisQuery()
2626
}}}";
2727
Assert.True(json.JsonEquals(expected), json);
2828
}
29+
30+
[Test]
31+
public void MoreLikeThisWithIds()
32+
{
33+
var s = new MoreLikeThisQueryDescriptor<ElasticsearchProject>()
34+
.Ids(new long[] { 1, 2, 3, 4 })
35+
.OnFields(p => p.Name);
36+
var json = TestElasticClient.Serialize(s);
37+
38+
var expected = @"{
39+
fields: [ ""name""],
40+
ids: [ ""1"", ""2"", ""3"", ""4""],
41+
}";
42+
Assert.True(json.JsonEquals(expected), json);
43+
}
44+
45+
[Test]
46+
public void MoreLikeThisWithDocuments()
47+
{
48+
var s = new MoreLikeThisQueryDescriptor<ElasticsearchProject>()
49+
.OnFields(p => p.Name)
50+
.Documents(d=>d
51+
.Get(1, g=>g.Fields(p=>p.Product.Name).Routing("routing_value"))
52+
.Get<Person>("some-string-id", g=>g.Routing("routing_value").Type("people").Index("different_index"))
53+
);
54+
var json = TestElasticClient.Serialize(s);
55+
56+
var expected = @"{
57+
fields: [ ""name""],
58+
docs: [
59+
{
60+
_index: ""nest_test_data"",
61+
_type: ""elasticsearchprojects"",
62+
_id: ""1"",
63+
fields: [
64+
""product.name""
65+
],
66+
_routing: ""routing_value""
67+
},
68+
{
69+
_index: ""different_index"",
70+
_type: ""people"",
71+
_id: ""some-string-id"",
72+
_routing: ""routing_value""
73+
}]
74+
}";
75+
Assert.True(json.JsonEquals(expected), json);
76+
}
77+
78+
[Test]
79+
public void MoreLikeThisWithDocumentsExplicit()
80+
{
81+
var s = new MoreLikeThisQueryDescriptor<ElasticsearchProject>()
82+
.OnFields(p => p.Name)
83+
.DocumentsExplicit(d=>d
84+
.Get(1, g=>g.Fields(p=>p.Product.Name).Routing("routing_value"))
85+
.Get<Person>("some-string-id", g=>g.Routing("routing_value").Type("people").Index("different_index"))
86+
);
87+
var json = TestElasticClient.Serialize(s);
88+
89+
//NEST should default to not sending index but when specified explicitly it should not force it null
90+
var expected = @"{
91+
fields: [ ""name""],
92+
docs: [
93+
{
94+
_type: ""elasticsearchprojects"",
95+
_id: ""1"",
96+
fields: [
97+
""product.name""
98+
],
99+
_routing: ""routing_value""
100+
},
101+
{
102+
_index: ""different_index"",
103+
_type: ""people"",
104+
_id: ""some-string-id"",
105+
_routing: ""routing_value""
106+
}]
107+
}";
108+
Assert.True(json.JsonEquals(expected), json);
109+
}
110+
29111
[Test]
30112
public void TestMoreLikeThisAllQuery()
31113
{

0 commit comments

Comments
 (0)
Please sign in to comment.