Skip to content

Feature/percolate query #2063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
:ref_current: https://www.elastic.co/guide/en/elasticsearch/reference/master

:github: https://github.com/elastic/elasticsearch-net

:nuget: https://www.nuget.org/packages

[[percolate-query-usage]]
== Percolate Query Usage

The percolate query can be used to match queries stored in an index.
The percolate query itself contains the document that will be used as query to match with the stored queries.

IMPORTANT: In order for the percolate query to work, the index in which your stored queries reside must contain
a mapping for documents that you wish to percolate, so that they are parsed correctly at query time.

See the Elasticsearch documentation on {ref_current}/query-dsl-percolate-query.html[percolate query] for more details.

In this example, we have a document stored with a `query` field that is mapped as a `percolator` type. This field
contains a `match` query.

[source,csharp]
----
foreach (var index in values.Values)
{
this.Client.CreateIndex(index, c => c
.Mappings(m => m
.Map<Project>(mm => mm.AutoMap()
.Properties(Seeder.ProjectProperties)
)
.Map<PercolatedQuery>(mm => mm.AutoMap()
.Properties(Seeder.PercolatedQueryProperties)
)
)
);

this.Client.Index(new PercolatedQuery
{
Id = PercolatorId,
Query = new QueryContainer(new MatchQuery
{
Field = Infer.Field<Project>(f => f.LeadDeveloper.FirstName),
Query = "Martijn"
})
}, d => d.Index(index));

this.Client.Refresh(index);
}
----

=== Fluent DSL Example

[source,csharp]
----
f =>
f.Query(QueryFluent).Index(CallIsolatedValue).AllTypes()
----

=== Object Initializer Syntax Example

[source,csharp]
----
new SearchRequest<PercolatedQuery>(CallIsolatedValue, Types.All)
{
Query = this.QueryInitializer
}
----

[source,javascript]
.Example json output
----
{
"percolator": {
"document_type": "project",
"document": {
"name": "Koch, Collier and Mohr",
"state": "BellyUp",
"startedOn": "2015-01-01T00:00:00",
"lastActivity": "0001-01-01T00:00:00",
"leadDeveloper": {
"gender": "Male",
"id": 0,
"firstName": "Martijn",
"lastName": "Laarman"
},
"location": {
"lat": 42.1523,
"lon": -80.321
}
}
}
}
----

=== Fluent DSL Example

[source,csharp]
----
q
.Percolate(p => p
.DocumentType(typeof(Project))
.Document(Project.Instance)
)
----

=== Object Initializer Syntax Example

[source,csharp]
----
new PercolateQuery
{
DocumentType = typeof(Project),
Document = Project.Instance,
}
----

=== Handling Responses

[source,csharp]
----
response.Total.Should().BeGreaterThan(0);
response.Hits.Should().NotBeNull();
response.Hits.Count().Should().BeGreaterThan(0);
var match = response.Documents.First();
match.Id.Should().Be(PercolatorId);
((IQueryContainer)match.Query).Match.Should().NotBeNull();
----

[[percolate-an-existing-document]]
[float]
== Percolate an existing document

Instead of specifying a the source of the document being percolated, the source can also be
retrieved from an already stored document. The percolate query will then internally execute a get request to fetch that document.

The required fields to percolate an existing document are:

* `index` in which the document resides

* `type` of the document

* `id` of the document

* `document_type` type / mapping of the document

See the Elasticsearch documentation on {ref_current}/query-dsl-percolate-query.html[percolate query] for more details.

[source,csharp]
----
foreach (var index in values.Values)
{
this.Client.CreateIndex(index, c => c
.Mappings(m => m
.Map<Project>(mm => mm.AutoMap()
.Properties(Seeder.ProjectProperties)
)
.Map<PercolatedQuery>(mm => mm.AutoMap()
.Properties(Seeder.PercolatedQueryProperties)
)
)
);

this.Client.Index(new PercolatedQuery
{
Id = PercolatorId,
Query = new QueryContainer(new MatchQuery
{
Field = Infer.Field<Project>(f => f.LeadDeveloper.FirstName),
Query = "Martijn"
})
}, d => d.Index(index));

this.Client.Index(Project.Instance);
this.Client.Refresh(Nest.Indices.Index(index).And<Project>());
}
----

=== Fluent DSL Example

[source,csharp]
----
f =>
f.Query(QueryFluent).Index(CallIsolatedValue).AllTypes()
----

=== Object Initializer Syntax Example

[source,csharp]
----
new SearchRequest<PercolatedQuery>(CallIsolatedValue, Types.All)
{
Query = this.QueryInitializer
}
----

[source,javascript]
.Example json output
----
{
"percolator": {
"type": "project",
"index": "project",
"id": "Durgan LLC",
"document_type": "project"
}
}
----

=== Fluent DSL Example

[source,csharp]
----
q
.Percolate(p => p
.Type<Project>()
.Index<Project>()
.Id(Project.Instance.Name)
.DocumentType<Project>() <1>
)
----
<1> specify the `type`, `index`, `id` and `document_type` of the document to fetch, to percolate.

=== Object Initializer Syntax Example

[source,csharp]
----
new PercolateQuery
{
Type = typeof(Project),
Index = IndexName.From<Project>(),
Id = Project.Instance.Name,
DocumentType = typeof(Project)
}
----

=== Handling Responses

[source,csharp]
----
response.Total.Should().BeGreaterThan(0);
response.Hits.Should().NotBeNull();
response.Hits.Count().Should().BeGreaterThan(0);
var match = response.Documents.First();
match.Id.Should().Be(PercolatorId);
((IQueryContainer)match.Query).Match.Should().NotBeNull();
----

10 changes: 5 additions & 5 deletions paket.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
NUGET
remote: https://www.nuget.org/api/v2
remote: http://api.nuget.org/v3/index.json
specs:
AsciiDocNet (1.0.0-alpha3)
SemanticVersioning (0.6.17)
ShellProgressBar (3.0)
remote: https://www.nuget.org/api/v2
specs:
Bogus (3.0.5-beta-2)
Newtonsoft.Json (>= 8.0.2) - framework: >= net40, dnx451, dnxcore50
System.ComponentModel (>= 4.0.1-beta-23516) - framework: dnxcore50
Expand Down Expand Up @@ -348,10 +352,6 @@ NUGET
System.Threading.Tasks (>= 4.0) - framework: dnxcore50
xunit.abstractions (>= 2.0) - framework: dnxcore50
xunit.extensibility.core (2.1) - framework: >= net45, dnx451, dnxcore50, monoandroid, monotouch, xamarinios, winv4.5, wpv8.0, wpav8.1
remote: http://api.nuget.org/v3/index.json
specs:
SemanticVersioning (0.6.17)
ShellProgressBar (3.0)

GROUP build
NUGET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ public override void Visit(Document document)
_newDocument.Attributes.Add(attributeEntry);
}

if (!document.Attributes.Any(a => a.Name == "ref_current"))
if (document.Attributes.All(a => a.Name != "ref_current"))
{
_newDocument.Attributes.Add(new AttributeEntry("ref_current", "https://www.elastic.co/guide/en/elasticsearch/reference/current"));
_newDocument.Attributes.Add(new AttributeEntry("ref_current", "https://www.elastic.co/guide/en/elasticsearch/reference/master"));
}

if (!document.Attributes.Any(a => a.Name == "github"))
if (document.Attributes.All(a => a.Name != "github"))
{
_newDocument.Attributes.Add(new AttributeEntry("github", "https://github.com/elastic/elasticsearch-net"));
}

if (!document.Attributes.Any(a => a.Name == "nuget"))
if (document.Attributes.All(a => a.Name != "nuget"))
{
_newDocument.Attributes.Add(new AttributeEntry("nuget", "https://www.nuget.org/packages"));
}
Expand Down
6 changes: 1 addition & 5 deletions src/Elasticsearch.Net/Connection/HttpConnection-CoreFx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ public class HttpConnection : IConnection
private readonly object _lock = new object();
private readonly ConcurrentDictionary<int, HttpClient> _clients = new ConcurrentDictionary<int, HttpClient>();

private string DefaultContentType => "application/json";

public HttpConnection() { }

private HttpClient GetClient(RequestData requestData)
{
var hashCode = requestData.GetHashCode();
Expand Down Expand Up @@ -127,7 +123,7 @@ private static HttpRequestMessage CreateHttpRequestMessage(RequestData requestDa
requestMessage.Headers.TryAddWithoutValidation(key, requestData.Headers.GetValues(key));
}

requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestData.ContentType));
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(requestData.Accept));

if (!requestData.RunAs.IsNullOrEmpty())
requestMessage.Headers.Add("es-shield-runas-user", requestData.RunAs);
Expand Down
1 change: 0 additions & 1 deletion src/Elasticsearch.Net/Domain/IPropertyMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@ public class PropertyMapping : IPropertyMapping
/// <pre>- When Indexing this type do not serialize whatever this value hold</pre>
/// </summary>
public bool Ignore { get; set; }

}
}
15 changes: 15 additions & 0 deletions src/Nest/CommonAbstractions/Infer/Id/IdExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Nest
{
internal static class IdExtensions
{
internal static bool IsConditionless(this Id id)
{
return id == null || (id.Value == null && id.Document == null);
}
}
}
2 changes: 1 addition & 1 deletion src/Nest/CommonAbstractions/Infer/Indices/Indices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ public override int GetHashCode()
);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Nest
{
public static class PropertyNameExtensions
internal static class PropertyNameExtensions
{
internal static bool IsConditionless(this PropertyName property)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
namespace Nest
{
public static class TypeNameExtensions
internal static class TypeNameExtensions
{

public static bool IsConditionless(this TypeName marker)
internal static bool IsConditionless(this TypeName marker)
{
return marker == null || marker.Name.IsNullOrEmpty() && marker.Type == null;
}
}
}
}
Loading