Skip to content

Commit 0b4dfd5

Browse files
1.1.0 Release
Notable changes: * Support for JanusGraph 1.1.0 * Gremlin.Net updated to 3.7.3 (JanusGraph 1.1.0 also uses TinkerPop 3.7.3) * Missing text predicates added (mostly negations, but also `TextContainsPhrase`) Fixes #165 Signed-off-by: Florian Hockmann <fh@florian-hockmann.de>
1 parent 5375dfd commit 0b4dfd5

File tree

6 files changed

+209
-17
lines changed

6 files changed

+209
-17
lines changed

.github/workflows/linter.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,7 @@ jobs:
4141
env:
4242
VALIDATE_ALL_CODEBASE: false
4343
VALIDATE_JSCPD: false # need to find a way to ignore license headers for duplicate detection
44+
VALIDATE_JSON_PRETTIER: false # this unfortunately conflicts with our .editorconfig for no final new line
45+
VALIDATE_MARKDOWN_PRETTIER: false # this unfortunately conflicts with our .editorconfig for no final new line
4446
DEFAULT_BRANCH: master
4547
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,14 @@ The lowest supported JanusGraph version is 0.3.0.
9595
The following table shows the supported JanusGraph versions for each version
9696
of JanusGraph.Net:
9797

98-
| JanusGraph.Net | JanusGraph |
99-
| -------------- | ---------------------- |
100-
| 0.1.z | 0.3.z |
101-
| 0.2.z | 0.4.z, 0.5.z |
102-
| 0.3.z | 0.4.z, 0.5.z, 0.6.z |
103-
| 0.4.z | (0.4.z, 0.5.z,) 0.6.z |
104-
| 1.0.z | (0.6.z,) 1.0.z |
98+
| JanusGraph.Net | JanusGraph |
99+
| -------------- | --------------------- |
100+
| 0.1.z | 0.3.z |
101+
| 0.2.z | 0.4.z, 0.5.z |
102+
| 0.3.z | 0.4.z, 0.5.z, 0.6.z |
103+
| 0.4.z | (0.4.z, 0.5.z,) 0.6.z |
104+
| 1.0.z | (0.6.z,) 1.0.z |
105+
| 1.1.z | 1.0.0, 1.1.z |
105106

106107
While it should also be possible to use JanusGraph.Net with other versions of
107108
JanusGraph than mentioned here, compatibility is not tested and some
@@ -132,7 +133,7 @@ Not all of the JanusGraph-specific types are already supported by both formats:
132133
| Format | RelationIdentifier | Text predicates | Geoshapes | Geo predicates |
133134
| ----------- | ------------------ | --------------- | --------- | -------------- |
134135
| GraphSON3 | x | x | `Point` | - |
135-
| GraphBinary | x | x | `Point`* | - |
136+
| GraphBinary | x | x | `Point`\* | - |
136137

137138
\* Since version 1.0.0 of JanusGraph.Net.
138139
JanusGraph also needs to be on version 1.0.0 or higher.

src/JanusGraph.Net/JanusGraph.Net.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
99
<LangVersion>12</LangVersion>
1010
<Nullable>enable</Nullable>
11-
<Version>1.0.0</Version>
11+
<Version>1.1.0</Version>
1212
<Title>JanusGraph.Net</Title>
1313
<Authors>JanusGraph</Authors>
1414
<Description>

src/JanusGraph.Net/Text.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,41 @@ public static class Text
3434
/// <returns>The text predicate.</returns>
3535
public static P TextContains(string query) => new JanusGraphP("textContains", query);
3636

37+
/// <summary>
38+
/// Is true if no words inside the text string match the query string.
39+
/// </summary>
40+
/// <param name="query">The query to search.</param>
41+
/// <returns>The text predicate.</returns>
42+
public static P TextNotContains(string query) => new JanusGraphP("textNotContains", query);
43+
3744
/// <summary>
3845
/// Is true if (at least) one word inside the text string begins with the query string.
3946
/// </summary>
4047
/// <param name="query">The query to search.</param>
4148
/// <returns>The text predicate.</returns>
4249
public static P TextContainsPrefix(string query) => new JanusGraphP("textContainsPrefix", query);
4350

51+
/// <summary>
52+
/// Is true if no words inside the text string begin with the query string.
53+
/// </summary>
54+
/// <param name="query">The query to search.</param>
55+
/// <returns>The text predicate.</returns>
56+
public static P TextNotContainsPrefix(string query) => new JanusGraphP("textNotContainsPrefix", query);
57+
4458
/// <summary>
4559
/// Is true if (at least) one word inside the text string matches the given regular expression.
4660
/// </summary>
4761
/// <param name="regex">The regular expression.</param>
4862
/// <returns>The text predicate.</returns>
4963
public static P TextContainsRegex(string regex) => new JanusGraphP("textContainsRegex", regex);
64+
65+
/// <summary>
66+
/// Is true if no words inside the text string match the given regular expression.
67+
/// </summary>
68+
/// <param name="regex">The regular expression.</param>
69+
/// <returns>The text predicate.</returns>
70+
public static P TextNotContainsRegex(string regex) => new JanusGraphP("textNotContainsRegex", regex);
71+
5072
/// <summary>
5173
/// Is true if (at least) one word inside the text string is similar to the query String (based on
5274
/// Levenshtein edit distance).
@@ -55,25 +77,69 @@ public static class Text
5577
/// <returns>The text predicate.</returns>
5678
public static P TextContainsFuzzy(string query) => new JanusGraphP("textContainsFuzzy", query);
5779

80+
/// <summary>
81+
/// Is true if no words inside the text string are similar to the query string (based on Levenshtein edit
82+
/// distance).
83+
/// </summary>
84+
/// <param name="query">The query to search.</param>
85+
/// <returns>The text predicate.</returns>
86+
public static P TextNotContainsFuzzy(string query) => new JanusGraphP("textNotContainsFuzzy", query);
87+
88+
/// <summary>
89+
/// Is true if the text string does contain the sequence of words in the query string.
90+
/// </summary>
91+
/// <param name="query">The query to search.</param>
92+
/// <returns>The text predicate.</returns>
93+
public static P TextContainsPhrase(string query) => new JanusGraphP("textContainsPhrase", query);
94+
95+
/// <summary>
96+
/// Is true if the text string does not contain the sequence of words in the query string.
97+
/// </summary>
98+
/// <param name="query">The query to search.</param>
99+
/// <returns>The text predicate.</returns>
100+
public static P TextNotContainsPhrase(string query) => new JanusGraphP("textNotContainsPhrase", query);
101+
58102
/// <summary>
59103
/// Is true if the string value starts with the given query string.
60104
/// </summary>
61105
/// <param name="query">The query to search.</param>
62106
/// <returns>The text predicate.</returns>
63107
public static P TextPrefix(string query) => new JanusGraphP("textPrefix", query);
64108

109+
/// <summary>
110+
/// Is true if the string value does not start with the given query string.
111+
/// </summary>
112+
/// <param name="query">The query to search.</param>
113+
/// <returns>The text predicate.</returns>
114+
public static P TextNotPrefix(string query) => new JanusGraphP("textNotPrefix", query);
115+
65116
/// <summary>
66117
/// Is true if the string value matches the given regular expression in its entirety.
67118
/// </summary>
68119
/// <param name="regex">The regular expression.</param>
69120
/// <returns>The text predicate.</returns>
70121
public static P TextRegex(string regex) => new JanusGraphP("textRegex", regex);
71122

123+
/// <summary>
124+
/// Is true if the string value does not match the given regular expression in its entirety.
125+
/// </summary>
126+
/// <param name="regex">The regular expression.</param>
127+
/// <returns>The text predicate.</returns>
128+
public static P TextNotRegex(string regex) => new JanusGraphP("textNotRegex", regex);
129+
72130
/// <summary>
73131
/// Is true if the string value is similar to the given query string (based on Levenshtein edit distance).
74132
/// </summary>
75133
/// <param name="query">The query to search.</param>
76134
/// <returns>The text predicate.</returns>
77135
public static P TextFuzzy(string query) => new JanusGraphP("textFuzzy", query);
136+
137+
/// <summary>
138+
/// Is true if the string value is not similar to the given query string (based on Levenshtein edit
139+
/// distance).
140+
/// </summary>
141+
/// <param name="query">The query to search.</param>
142+
/// <returns>The text predicate.</returns>
143+
public static P TextNotFuzzy(string query) => new JanusGraphP("textNotFuzzy", query);
78144
}
79145
}

test/JanusGraph.Net.IntegrationTest/TextTests.cs

Lines changed: 130 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public abstract class TextTests : IDisposable
3333
[Theory]
3434
[InlineData("loves", 2)]
3535
[InlineData("shouldNotBeFound", 0)]
36-
public async Task TextContainsgivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
36+
public async Task TextContainsGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
3737
{
3838
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
3939

@@ -42,11 +42,23 @@ public async Task TextContainsgivenSearchText_ExpectedCountOfElements(string sea
4242
Assert.Equal(expectedCount, count);
4343
}
4444

45+
[Theory]
46+
[InlineData("loves", 1)]
47+
[InlineData("shouldNotBeFound", 3)]
48+
public async Task TextNotContainsGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
49+
{
50+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
51+
52+
var count = await g.E().Has("reason", Text.TextNotContains(searchText)).Count().Promise(t => t.Next());
53+
54+
Assert.Equal(expectedCount, count);
55+
}
56+
4557
[Theory]
4658
[InlineData("wave", 1)]
4759
[InlineData("f", 2)]
4860
[InlineData("shouldNotBeFound", 0)]
49-
public async Task TextContainsPrefixgivenSearchText_ExpectedCountOfElements(string searchText,
61+
public async Task TextContainsPrefixGivenSearchText_ExpectedCountOfElements(string searchText,
5062
int expectedCount)
5163
{
5264
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
@@ -56,11 +68,26 @@ public async Task TextContainsPrefixgivenSearchText_ExpectedCountOfElements(stri
5668
Assert.Equal(expectedCount, count);
5769
}
5870

71+
[Theory]
72+
[InlineData("wave", 2)]
73+
[InlineData("f", 1)]
74+
[InlineData("shouldNotBeFound", 3)]
75+
public async Task TextNotContainsPrefixGivenSearchText_ExpectedCountOfElements(string searchText,
76+
int expectedCount)
77+
{
78+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
79+
80+
var count = await g.E().Has("reason", Text.TextNotContainsPrefix(searchText)).Count()
81+
.Promise(t => t.Next());
82+
83+
Assert.Equal(expectedCount, count);
84+
}
85+
5986
[Theory]
6087
[InlineData(".*ave.*", 1)]
6188
[InlineData("f.{3,4}", 2)]
6289
[InlineData("shouldNotBeFound", 0)]
63-
public async Task TextContainsRegexgivenRegex_ExpectedCountOfElements(string regex, int expectedCount)
90+
public async Task TextContainsRegexGivenRegex_ExpectedCountOfElements(string regex, int expectedCount)
6491
{
6592
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
6693

@@ -69,10 +96,23 @@ public async Task TextContainsRegexgivenRegex_ExpectedCountOfElements(string reg
6996
Assert.Equal(expectedCount, count);
7097
}
7198

99+
[Theory]
100+
[InlineData(".*ave.*", 2)]
101+
[InlineData("f.{3,4}", 1)]
102+
[InlineData("shouldNotBeFound", 3)]
103+
public async Task TextNotContainsRegexGivenRegex_ExpectedCountOfElements(string regex, int expectedCount)
104+
{
105+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
106+
107+
var count = await g.E().Has("reason", Text.TextNotContainsRegex(regex)).Count().Promise(t => t.Next());
108+
109+
Assert.Equal(expectedCount, count);
110+
}
111+
72112
[Theory]
73113
[InlineData("waxes", 1)]
74114
[InlineData("shouldNotBeFound", 0)]
75-
public async Task TextContainsFuzzygivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
115+
public async Task TextContainsFuzzyGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
76116
{
77117
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
78118

@@ -81,11 +121,55 @@ public async Task TextContainsFuzzygivenSearchText_ExpectedCountOfElements(strin
81121
Assert.Equal(expectedCount, count);
82122
}
83123

124+
[Theory]
125+
[InlineData("waxes", 2)]
126+
[InlineData("shouldNotBeFound", 3)]
127+
public async Task TextNotContainsFuzzyGivenSearchText_ExpectedCountOfElements(string searchText,
128+
int expectedCount)
129+
{
130+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
131+
132+
var count = await g.E().Has("reason", Text.TextNotContainsFuzzy(searchText)).Count().Promise(t => t.Next());
133+
134+
Assert.Equal(expectedCount, count);
135+
}
136+
137+
[Theory]
138+
[InlineData("fresh breezes", 1)]
139+
[InlineData("no fear", 1)]
140+
[InlineData("fear of", 1)]
141+
[InlineData("shouldNotBeFound", 0)]
142+
public async Task TextContainsPhraseGivenSearchText_ExpectedCountOfElements(string searchText,
143+
int expectedCount)
144+
{
145+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
146+
147+
var count = await g.E().Has("reason", Text.TextContainsPhrase(searchText)).Count().Promise(t => t.Next());
148+
149+
Assert.Equal(expectedCount, count);
150+
}
151+
152+
[Theory]
153+
[InlineData("fresh breezes", 2)]
154+
[InlineData("no fear", 2)]
155+
[InlineData("fear of", 2)]
156+
[InlineData("shouldNotBeFound", 3)]
157+
public async Task TextNotContainsPhraseGivenSearchText_ExpectedCountOfElements(string searchText,
158+
int expectedCount)
159+
{
160+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
161+
162+
var count = await g.E().Has("reason", Text.TextNotContainsPhrase(searchText)).Count()
163+
.Promise(t => t.Next());
164+
165+
Assert.Equal(expectedCount, count);
166+
}
167+
84168
[Theory]
85169
[InlineData("herc", 1)]
86170
[InlineData("s", 3)]
87171
[InlineData("shouldNotBeFound", 0)]
88-
public async Task TextPrefixgivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
172+
public async Task TextPrefixGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
89173
{
90174
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
91175

@@ -94,11 +178,24 @@ public async Task TextPrefixgivenSearchText_ExpectedCountOfElements(string searc
94178
Assert.Equal(expectedCount, count);
95179
}
96180

181+
[Theory]
182+
[InlineData("herc", 11)]
183+
[InlineData("s", 9)]
184+
[InlineData("shouldNotBeFound", 12)]
185+
public async Task TextNotPrefixGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
186+
{
187+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
188+
189+
var count = await g.V().Has("name", Text.TextNotPrefix(searchText)).Count().Promise(t => t.Next());
190+
191+
Assert.Equal(expectedCount, count);
192+
}
193+
97194
[Theory]
98195
[InlineData(".*rcule.*", 1)]
99196
[InlineData("s.{2}", 2)]
100197
[InlineData("shouldNotBeFound", 0)]
101-
public async Task TextRegexgivenRegex_ExpectedCountOfElements(string regex, int expectedCount)
198+
public async Task TextRegexGivenRegex_ExpectedCountOfElements(string regex, int expectedCount)
102199
{
103200
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
104201

@@ -107,11 +204,24 @@ public async Task TextRegexgivenRegex_ExpectedCountOfElements(string regex, int
107204
Assert.Equal(expectedCount, count);
108205
}
109206

207+
[Theory]
208+
[InlineData(".*rcule.*", 11)]
209+
[InlineData("s.{2}", 10)]
210+
[InlineData("shouldNotBeFound", 12)]
211+
public async Task TextNotRegexGivenRegex_ExpectedCountOfElements(string regex, int expectedCount)
212+
{
213+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
214+
215+
var count = await g.V().Has("name", Text.TextNotRegex(regex)).Count().Promise(t => t.Next());
216+
217+
Assert.Equal(expectedCount, count);
218+
}
219+
110220
[Theory]
111221
[InlineData("herculex", 1)]
112222
[InlineData("ska", 2)]
113223
[InlineData("shouldNotBeFound", 0)]
114-
public async Task TextFuzzygivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
224+
public async Task TextFuzzyGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
115225
{
116226
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
117227

@@ -120,6 +230,19 @@ public async Task TextFuzzygivenSearchText_ExpectedCountOfElements(string search
120230
Assert.Equal(expectedCount, count);
121231
}
122232

233+
[Theory]
234+
[InlineData("herculex", 11)]
235+
[InlineData("ska", 10)]
236+
[InlineData("shouldNotBeFound", 12)]
237+
public async Task TextNotFuzzyGivenSearchText_ExpectedCountOfElements(string searchText, int expectedCount)
238+
{
239+
var g = Traversal().WithRemote(ConnectionFactory.CreateRemoteConnection());
240+
241+
var count = await g.V().Has("name", Text.TextNotFuzzy(searchText)).Count().Promise(t => t.Next());
242+
243+
Assert.Equal(expectedCount, count);
244+
}
245+
123246
public void Dispose()
124247
{
125248
ConnectionFactory?.Dispose();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"dockerImage": "janusgraph/janusgraph:1.0.0"
2+
"dockerImage": "janusgraph/janusgraph:1.1.0"
33
}

0 commit comments

Comments
 (0)