diff --git a/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj b/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj
index 857ab0c6aa1..c499024bfe7 100644
--- a/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj
+++ b/src/Nest.Tests.Unit/Nest.Tests.Unit.csproj
@@ -108,6 +108,7 @@
+
diff --git a/src/Nest.Tests.Unit/Search/Query/Singles/HasChildQueryJson.cs b/src/Nest.Tests.Unit/Search/Query/Singles/HasChildQueryJson.cs
index 7d7e9b80e47..940032bdb6e 100644
--- a/src/Nest.Tests.Unit/Search/Query/Singles/HasChildQueryJson.cs
+++ b/src/Nest.Tests.Unit/Search/Query/Singles/HasChildQueryJson.cs
@@ -16,6 +16,7 @@ public void HasChildThisQuery()
.HasChild(fz => fz
.Query(qq=>qq.Term(f=>f.FirstName, "john"))
.Scope("my_scope")
+ .Score(ChildScoreType.avg)
)
);
var json = TestElasticClient.Serialize(s);
@@ -23,6 +24,7 @@ public void HasChildThisQuery()
{ has_child: {
type: ""people"",
_scope: ""my_scope"",
+ score_type: ""avg"",
query: {
term: {
firstName: {
diff --git a/src/Nest.Tests.Unit/Search/Query/Singles/HasParentQueryJson.cs b/src/Nest.Tests.Unit/Search/Query/Singles/HasParentQueryJson.cs
new file mode 100644
index 00000000000..74db6d7af41
--- /dev/null
+++ b/src/Nest.Tests.Unit/Search/Query/Singles/HasParentQueryJson.cs
@@ -0,0 +1,41 @@
+using NUnit.Framework;
+using Nest.Tests.MockData.Domain;
+
+namespace Nest.Tests.Unit.Search.Query.Singles
+{
+ [TestFixture]
+ public class HasParentQueryJson
+ {
+ [Test]
+ public void HasParentThisQuery()
+ {
+ var s = new SearchDescriptor()
+ .From(0)
+ .Size(10)
+ .Query(q => q
+ .HasParent(fz => fz
+ .Query(qq=>qq.Term(f=>f.FirstName, "john"))
+ .Scope("my_scope")
+ .Score()
+ )
+ );
+ var json = TestElasticClient.Serialize(s);
+ var expected = @"{ from: 0, size: 10, query :
+ { has_parent: {
+ type: ""people"",
+ _scope: ""my_scope"",
+ score_type: ""score"",
+ query: {
+ term: {
+ firstName: {
+ value: ""john""
+ }
+ }
+ }
+
+ }}}";
+ Assert.True(json.JsonEquals(expected), json);
+ }
+
+ }
+}
diff --git a/src/Nest/DSL/IQueryDescriptor.cs b/src/Nest/DSL/IQueryDescriptor.cs
index 9846cb37c31..c88645d6ad4 100644
--- a/src/Nest/DSL/IQueryDescriptor.cs
+++ b/src/Nest/DSL/IQueryDescriptor.cs
@@ -17,6 +17,7 @@ interface IQueryDescriptor
BaseQuery FuzzyLikeThis(Action> selector);
BaseQuery FuzzyNumeric(Action> selector);
BaseQuery HasChild(Action> selector) where K : class;
+ BaseQuery HasParent(Action> selector) where K : class;
BaseQuery Ids(IEnumerable types, IEnumerable values);
BaseQuery Ids(IEnumerable values);
BaseQuery Ids(string type, IEnumerable values);
diff --git a/src/Nest/DSL/Query/ChildScoreType.cs b/src/Nest/DSL/Query/ChildScoreType.cs
new file mode 100644
index 00000000000..ee69931a3df
--- /dev/null
+++ b/src/Nest/DSL/Query/ChildScoreType.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Nest
+{
+ public enum ChildScoreType
+ {
+ none,
+ avg,
+ sum,
+ max
+ }
+}
diff --git a/src/Nest/DSL/Query/HasChildQueryDescriptor.cs b/src/Nest/DSL/Query/HasChildQueryDescriptor.cs
index f8796f588eb..97a6adc3cad 100644
--- a/src/Nest/DSL/Query/HasChildQueryDescriptor.cs
+++ b/src/Nest/DSL/Query/HasChildQueryDescriptor.cs
@@ -5,6 +5,7 @@
using Newtonsoft.Json;
using System.Linq.Expressions;
using Nest.Resolvers;
+using Newtonsoft.Json.Converters;
namespace Nest
{
@@ -29,6 +30,10 @@ public HasChildQueryDescriptor()
[JsonProperty("_scope")]
internal string _Scope { get; set; }
+ [JsonProperty("score_type")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ internal ChildScoreType? _ScoreType { get; set; }
+
[JsonProperty("query")]
internal BaseQuery _QueryDescriptor { get; set; }
@@ -48,6 +53,14 @@ public HasChildQueryDescriptor Type(string type)
this._Type = type;
return this;
}
+
+ public HasChildQueryDescriptor Score(ChildScoreType? scoreType)
+ {
+ this._ScoreType = scoreType;
+ return this;
+ }
+
+
[JsonProperty(PropertyName = "_cache")]
internal bool? _Cache { get; set; }
diff --git a/src/Nest/DSL/Query/HasParentQueryDescriptor.cs b/src/Nest/DSL/Query/HasParentQueryDescriptor.cs
new file mode 100644
index 00000000000..71c24d44916
--- /dev/null
+++ b/src/Nest/DSL/Query/HasParentQueryDescriptor.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json;
+using System.Linq.Expressions;
+using Nest.Resolvers;
+using Newtonsoft.Json.Converters;
+
+namespace Nest
+{
+ [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
+ public class HasParentQueryDescriptor : IQuery where T : class
+ {
+ internal bool IsConditionless
+ {
+ get
+ {
+ return this._QueryDescriptor == null || this._QueryDescriptor.IsConditionless;
+ }
+ }
+
+ public HasParentQueryDescriptor()
+ {
+ this._Type = new TypeNameResolver().GetTypeNameFor();
+ }
+ [JsonProperty("type")]
+ internal TypeNameMarker _Type { get; set; }
+
+ [JsonProperty("_scope")]
+ internal string _Scope { get; set; }
+
+ [JsonProperty("score_type")]
+ [JsonConverter(typeof(StringEnumConverter))]
+ internal ParentScoreType? _ScoreType { get; set; }
+
+ [JsonProperty("query")]
+ internal BaseQuery _QueryDescriptor { get; set; }
+
+ public HasParentQueryDescriptor Query(Func, BaseQuery> querySelector)
+ {
+ var q = new QueryDescriptor();
+ this._QueryDescriptor = querySelector(q);
+ return this;
+ }
+ public HasParentQueryDescriptor Scope(string scope)
+ {
+ this._Scope = scope;
+ return this;
+ }
+ public HasParentQueryDescriptor Type(string type)
+ {
+ this._Type = type;
+ return this;
+ }
+
+ public HasParentQueryDescriptor Score(ParentScoreType? scoreType = ParentScoreType.score)
+ {
+ _ScoreType = scoreType;
+ return this;
+ }
+
+ [JsonProperty(PropertyName = "_name")]
+ internal string _Name { get; set; }
+ }
+}
diff --git a/src/Nest/DSL/Query/ParentScoreType.cs b/src/Nest/DSL/Query/ParentScoreType.cs
new file mode 100644
index 00000000000..84386a3403f
--- /dev/null
+++ b/src/Nest/DSL/Query/ParentScoreType.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Nest
+{
+ public enum ParentScoreType
+ {
+ none = 0,
+ score
+ }
+}
diff --git a/src/Nest/DSL/QueryDescriptor.cs b/src/Nest/DSL/QueryDescriptor.cs
index ba5a935ac13..06c2a2d3864 100644
--- a/src/Nest/DSL/QueryDescriptor.cs
+++ b/src/Nest/DSL/QueryDescriptor.cs
@@ -64,6 +64,8 @@ public QueryDescriptor()
internal FuzzyLikeThisDescriptor FuzzyLikeThisDescriptor { get; set; }
[JsonProperty(PropertyName = "has_child")]
internal object HasChildQueryDescriptor { get; set; }
+ [JsonProperty(PropertyName = "has_parent")]
+ internal object HasParentQueryDescriptor { get; set; }
[JsonProperty(PropertyName = "mlt")]
internal MoreLikeThisQueryDescriptor MoreLikeThisDescriptor { get; set; }
[JsonProperty(PropertyName = "range")]
@@ -133,6 +135,7 @@ internal QueryDescriptor Clone()
FuzzyLikeThisDescriptor = FuzzyLikeThisDescriptor,
HasChildQueryDescriptor = HasChildQueryDescriptor,
+ HasParentQueryDescriptor = HasParentQueryDescriptor,
MoreLikeThisDescriptor = MoreLikeThisDescriptor,
RangeQueryDescriptor = RangeQueryDescriptor,
@@ -528,6 +531,21 @@ public BaseQuery HasChild(Action> selector) where
return new QueryDescriptor { HasChildQueryDescriptor = this.HasChildQueryDescriptor };
}
///
+ /// The has_child query works the same as the has_child filter, by automatically wrapping the filter with a
+ /// constant_score.
+ ///
+ /// Type of the child
+ public BaseQuery HasParent(Action> selector) where K : class
+ {
+ var query = new HasParentQueryDescriptor();
+ selector(query);
+ if (query.IsConditionless)
+ return CreateConditionlessQueryDescriptor(query);
+
+ this.HasParentQueryDescriptor = query;
+ return new QueryDescriptor { HasParentQueryDescriptor = this.HasParentQueryDescriptor };
+ }
+ ///
/// The top_children query runs the child query with an estimated hits size, and out of the hit docs, aggregates
/// it into parent docs. If there aren’t enough parent docs matching the requested from/size search request,
/// then it is run again with a wider (more hits) search.
diff --git a/src/Nest/Nest.csproj b/src/Nest/Nest.csproj
index 23c81db8d9e..c3f92a419d5 100644
--- a/src/Nest/Nest.csproj
+++ b/src/Nest/Nest.csproj
@@ -71,6 +71,9 @@
+
+
+