Skip to content

Commit bac97eb

Browse files
russcamMpdreamz
authored andcommitted
Add field_masking_span query (#2241)
Forward port of #2231
1 parent b18d14f commit bac97eb

File tree

15 files changed

+237
-24
lines changed

15 files changed

+237
-24
lines changed

docs/query-dsl-usage.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ include::query-dsl/nest-specific/raw/raw-query-usage.asciidoc[]
8686

8787
include::query-dsl/span/container/span-containing-query-usage.asciidoc[]
8888

89+
include::query-dsl/span/field-masking/span-field-masking-usage.asciidoc[]
90+
8991
include::query-dsl/span/first/span-first-query-usage.asciidoc[]
9092

9193
include::query-dsl/span/multi-term/span-multi-term-query-usage.asciidoc[]

docs/query-dsl.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ NEST exposes all of the query DSL endpoints available in Elasticsearch
9393

9494
* <<span-containing-query-usage,Span Containing Query Usage>>
9595

96+
* <<span-field-masking-usage,Span Field Masking Usage>>
97+
9698
* <<span-first-query-usage,Span First Query Usage>>
9799

98100
* <<span-multi-term-query-usage,Span Multi Term Query Usage>>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/2.3
2+
3+
:github: https://github.com/elastic/elasticsearch-net
4+
5+
:nuget: https://www.nuget.org/packages
6+
7+
////
8+
IMPORTANT NOTE
9+
==============
10+
This file has been generated from https://github.com/elastic/elasticsearch-net/tree/2.x/src/Tests/QueryDsl/Span/FieldMasking/SpanFieldMaskingUsageTests.cs.
11+
If you wish to submit a PR for any spelling mistakes, typos or grammatical errors for this file,
12+
please modify the original csharp file found at the link and submit the PR with that change. Thanks!
13+
////
14+
15+
[[span-field-masking-usage]]
16+
== Span Field Masking Usage
17+
18+
=== Fluent DSL Example
19+
20+
[source,csharp]
21+
----
22+
q
23+
.SpanFieldMasking(c => c
24+
.Name("named_query")
25+
.Boost(1.1)
26+
.Field(p => p.Name)
27+
.Query(sq=>sq
28+
.SpanTerm(st=>st.Field(p=>p.Description).Value("dolorem"))
29+
)
30+
)
31+
----
32+
33+
=== Object Initializer Syntax Example
34+
35+
[source,csharp]
36+
----
37+
new SpanFieldMaskingQuery
38+
{
39+
Name = "named_query",
40+
Boost = 1.1,
41+
Field = Infer.Field<Project>(p => p.Name),
42+
Query = new SpanQuery
43+
{
44+
SpanTerm = new SpanTermQuery
45+
{
46+
Field = Infer.Field<Project>(p => p.Description),
47+
Value = "dolorem"
48+
}
49+
}
50+
}
51+
----
52+
53+
[source,javascript]
54+
.Example json output
55+
----
56+
{
57+
"field_masking_span": {
58+
"_name": "named_query",
59+
"boost": 1.1,
60+
"field": "name",
61+
"query": {
62+
"span_term": {
63+
"description": {
64+
"value": "dolorem"
65+
}
66+
}
67+
}
68+
}
69+
}
70+
----
71+

src/Nest/Nest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,7 @@
10241024
<Compile Include="QueryDsl\Operator.cs" />
10251025
<Compile Include="QueryDsl\Query.cs" />
10261026
<Compile Include="QueryDsl\Span\Containing\SpanContainingQuery.cs" />
1027+
<Compile Include="QueryDsl\Span\FieldMasking\SpanFieldMaskingQuery.cs" />
10271028
<Compile Include="QueryDsl\Span\First\SpanFirstQuery.cs" />
10281029
<Compile Include="QueryDsl\Span\ISpanSubQuery.cs" />
10291030
<Compile Include="QueryDsl\Span\MultiTerm\SpanMultiTermQuery.cs" />

src/Nest/QueryDsl/Abstractions/Container/IQueryContainer.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public interface IQueryContainer
111111
[JsonProperty("span_multi")]
112112
ISpanMultiTermQuery SpanMultiTerm { get; set; }
113113

114+
[JsonProperty("field_masking_span")]
115+
ISpanFieldMaskingQuery SpanFieldMasking { get; set; }
116+
114117
[JsonProperty("nested")]
115118
INestedQuery Nested { get; set; }
116119

src/Nest/QueryDsl/Abstractions/Container/QueryContainer-Assignments.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public partial class QueryContainer : IQueryContainer, IDescriptor
4343
private ISpanContainingQuery _spanContaining;
4444
private ISpanWithinQuery _spanWithin;
4545
private ISpanMultiTermQuery _spanMultiTerm;
46+
private ISpanFieldMaskingQuery _spanFieldMasking;
4647
private INestedQuery _nested;
4748
private IIndicesQuery _indices;
4849
private IFunctionScoreQuery _functionScore;
@@ -109,6 +110,7 @@ private T Set<T>(T value) where T : IQuery
109110
ISpanContainingQuery IQueryContainer.SpanContaining { get { return _spanContaining; } set { _spanContaining = Set(value); } }
110111
ISpanWithinQuery IQueryContainer.SpanWithin { get { return _spanWithin; } set { _spanWithin = Set(value); } }
111112
ISpanMultiTermQuery IQueryContainer.SpanMultiTerm { get { return _spanMultiTerm; } set { _spanMultiTerm = Set(value); } }
113+
ISpanFieldMaskingQuery IQueryContainer.SpanFieldMasking { get { return _spanFieldMasking; } set { _spanFieldMasking = Set(value); } }
112114
INestedQuery IQueryContainer.Nested { get { return _nested; } set { _nested = Set(value); } }
113115
IIndicesQuery IQueryContainer.Indices { get { return _indices; } set { _indices = Set(value); } }
114116
IFunctionScoreQuery IQueryContainer.FunctionScore { get { return _functionScore; } set { _functionScore = Set(value); } }
@@ -122,8 +124,5 @@ private T Set<T>(T value) where T : IQuery
122124
IExistsQuery IQueryContainer.Exists { get { return _exists; } set { _exists = Set(value); } }
123125
IMissingQuery IQueryContainer.Missing { get { return _missing; } set { _missing = Set(value); } }
124126
ITypeQuery IQueryContainer.Type { get { return _type; } set { _type = Set(value); } }
125-
126-
127127
}
128-
129128
}

src/Nest/QueryDsl/Abstractions/Container/QueryContainerDescriptor.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,15 @@ public QueryContainer SpanContaining(Func<SpanContainingQueryDescriptor<T>, ISpa
475475
public QueryContainer SpanWithin(Func<SpanWithinQueryDescriptor<T>, ISpanWithinQuery> selector) =>
476476
WrapInContainer(selector, (query, container) => container.SpanWithin = query);
477477

478+
/// <summary>
479+
/// Wraps span queries to allow them to participate in composite single-field Span queries by 'lying' about their search field.
480+
/// That is, the masked span query will function as normal, but the field points back to the set field of the query.
481+
/// This can be used to support queries like SpanNearQuery or SpanOrQuery across different fields,
482+
/// which is not ordinarily permitted.
483+
/// </summary>
484+
public QueryContainer SpanFieldMasking(Func<SpanFieldMaskingQueryDescriptor<T>, ISpanFieldMaskingQuery> selector) =>
485+
WrapInContainer(selector, (query, container) => container.SpanFieldMasking = query);
486+
478487
/// <summary>
479488
/// custom_score query allows to wrap another query and customize the scoring of it optionally with a
480489
/// computation derived from other field values in the doc (numeric ones) using script or boost expression

src/Nest/QueryDsl/Query.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
using System;
2-
using System.Collections;
3-
using System.Collections.Generic;
42
using System.Linq.Expressions;
53

64
namespace Nest
75
{
8-
// TODO: Write a unit test for these using reflection to make sure all queries are covered
96
public static class Query<T> where T : class
107
{
118
public static QueryContainer Bool(Func<BoolQueryDescriptor<T>, IBoolQuery> selector) =>
@@ -161,8 +158,11 @@ public static QueryContainer SpanTerm(Func<SpanTermQueryDescriptor<T>, ISpanTerm
161158
public static QueryContainer SpanWithin(Func<SpanWithinQueryDescriptor<T>, ISpanWithinQuery> selector) =>
162159
new QueryContainerDescriptor<T>().SpanWithin(selector);
163160

161+
public static QueryContainer SpanFieldMasking(Func<SpanFieldMaskingQueryDescriptor<T>, ISpanFieldMaskingQuery> selector) =>
162+
new QueryContainerDescriptor<T>().SpanFieldMasking(selector);
163+
164164
#pragma warning disable 618
165-
[Obsolete("Scheduled to be removed in 5.0. Setting Strict() at the container level does is a noop and must be set on each individual query.")]
165+
[Obsolete("Scheduled to be removed in 5.0. Setting Strict() at the container level is a noop and must be set on each individual query.")]
166166
public static QueryContainerDescriptor<T> Strict(bool strict = true) =>
167167
new QueryContainerDescriptor<T>().Strict(strict);
168168
#pragma warning restore 618
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Linq.Expressions;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using Newtonsoft.Json;
8+
9+
namespace Nest
10+
{
11+
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
12+
[JsonConverter(typeof(ReadAsTypeJsonConverter<SpanFieldMaskingQueryDescriptor<object>>))]
13+
public interface ISpanFieldMaskingQuery : ISpanSubQuery
14+
{
15+
[JsonProperty("field")]
16+
Field Field { get; set; }
17+
18+
[JsonProperty("query")]
19+
ISpanQuery Query { get; set; }
20+
}
21+
22+
public class SpanFieldMaskingQuery : QueryBase, ISpanFieldMaskingQuery
23+
{
24+
protected override bool Conditionless => IsConditionless(this);
25+
public ISpanQuery Query { get; set; }
26+
public Field Field { get; set; }
27+
28+
internal override void InternalWrapInContainer(IQueryContainer c) => c.SpanFieldMasking = this;
29+
internal static bool IsConditionless(ISpanFieldMaskingQuery q) =>
30+
q.Field.IsConditionless() || q.Query == null || q.Query.Conditionless;
31+
}
32+
33+
public class SpanFieldMaskingQueryDescriptor<T>
34+
: QueryDescriptorBase<SpanFieldMaskingQueryDescriptor<T>, ISpanFieldMaskingQuery>
35+
, ISpanFieldMaskingQuery where T : class
36+
{
37+
protected override bool Conditionless => SpanFieldMaskingQuery.IsConditionless(this);
38+
ISpanQuery ISpanFieldMaskingQuery.Query { get; set; }
39+
Field ISpanFieldMaskingQuery.Field { get; set; }
40+
41+
public SpanFieldMaskingQueryDescriptor<T> Field(Field field) => Assign(a => a.Field = field);
42+
43+
public SpanFieldMaskingQueryDescriptor<T> Field(Expression<Func<T, object>> objectPath) =>
44+
Assign(a => a.Field = objectPath);
45+
46+
public SpanFieldMaskingQueryDescriptor<T> Query(Func<SpanQueryDescriptor<T>, ISpanQuery> selector) =>
47+
Assign(a => a.Query = selector?.Invoke(new SpanQueryDescriptor<T>()));
48+
}
49+
}

src/Nest/QueryDsl/Span/SpanQuery.cs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,33 @@ namespace Nest
88
[JsonConverter(typeof(ReadAsTypeJsonConverter<SpanQueryDescriptor<object>>))]
99
public interface ISpanQuery : IQuery
1010
{
11-
[JsonProperty(PropertyName = "span_term")]
11+
[JsonProperty("span_term")]
1212
ISpanTermQuery SpanTerm { get; set; }
1313

14-
[JsonProperty(PropertyName = "span_first")]
14+
[JsonProperty("span_first")]
1515
ISpanFirstQuery SpanFirst { get; set; }
1616

17-
[JsonProperty(PropertyName = "span_near")]
17+
[JsonProperty("span_near")]
1818
ISpanNearQuery SpanNear { get; set; }
1919

20-
[JsonProperty(PropertyName = "span_or")]
20+
[JsonProperty("span_or")]
2121
ISpanOrQuery SpanOr { get; set; }
2222

23-
[JsonProperty(PropertyName = "span_not")]
23+
[JsonProperty("span_not")]
2424
ISpanNotQuery SpanNot { get; set; }
2525

26-
[JsonProperty(PropertyName = "span_containing")]
26+
[JsonProperty("span_containing")]
2727
ISpanContainingQuery SpanContaining { get; set; }
2828

29-
[JsonProperty(PropertyName = "span_within")]
29+
[JsonProperty("span_within")]
3030
ISpanWithinQuery SpanWithin { get; set; }
3131

32-
[JsonProperty(PropertyName = "span_multi")]
32+
[JsonProperty("span_multi")]
3333
ISpanMultiTermQuery SpanMultiTerm { get; set; }
3434

35+
[JsonProperty("field_masking_span")]
36+
ISpanFieldMaskingQuery SpanFieldMasking { get; set; }
37+
3538
void Accept(IQueryVisitor visitor);
3639
}
3740

@@ -52,6 +55,8 @@ public class SpanQuery : ISpanQuery
5255
public ISpanMultiTermQuery SpanMultiTerm { get; set; }
5356
public ISpanContainingQuery SpanContaining{ get; set; }
5457
public ISpanWithinQuery SpanWithin { get; set; }
58+
public ISpanFieldMaskingQuery SpanFieldMasking { get; set; }
59+
5560
public void Accept(IQueryVisitor visitor) => new QueryWalker().Walk(this, visitor);
5661

5762
internal static bool IsConditionless(ISpanQuery q) => new[]
@@ -61,7 +66,8 @@ internal static bool IsConditionless(ISpanQuery q) => new[]
6166
q.SpanNear,
6267
q.SpanOr ,
6368
q.SpanNot,
64-
q.SpanMultiTerm
69+
q.SpanMultiTerm,
70+
q.SpanFieldMasking
6571
}.All(sq => sq == null || sq.Conditionless);
6672
}
6773

@@ -77,6 +83,7 @@ public class SpanQueryDescriptor<T> : QueryDescriptorBase<SpanQueryDescriptor<T>
7783
ISpanMultiTermQuery ISpanQuery.SpanMultiTerm { get; set; }
7884
ISpanContainingQuery ISpanQuery.SpanContaining{ get; set; }
7985
ISpanWithinQuery ISpanQuery.SpanWithin { get; set; }
86+
ISpanFieldMaskingQuery ISpanQuery.SpanFieldMasking { get; set; }
8087

8188
public SpanQueryDescriptor<T> SpanTerm(Func<SpanTermQueryDescriptor<T>, ISpanTermQuery> selector) =>
8289
Assign(a => a.SpanTerm = selector?.Invoke(new SpanTermQueryDescriptor<T>()));
@@ -102,6 +109,9 @@ public SpanQueryDescriptor<T> SpanContaining(Func<SpanContainingQueryDescriptor<
102109
public SpanQueryDescriptor<T> SpanWithin(Func<SpanWithinQueryDescriptor<T>, ISpanWithinQuery> selector) =>
103110
Assign(a => a.SpanWithin = selector?.Invoke(new SpanWithinQueryDescriptor<T>()));
104111

112+
public SpanQueryDescriptor<T> SpanFieldMasking(Func<SpanFieldMaskingQueryDescriptor<T>, ISpanFieldMaskingQuery> selector) =>
113+
Assign(a => a.SpanFieldMasking = selector?.Invoke(new SpanFieldMaskingQueryDescriptor<T>()));
114+
105115
void ISpanQuery.Accept(IQueryVisitor visitor) => new QueryWalker().Walk(this, visitor);
106116

107117
}

0 commit comments

Comments
 (0)