Skip to content

[DE-392] nested search support #460

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 2 commits into from
Sep 15, 2022
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
4 changes: 2 additions & 2 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ jobs:
docker-img:
- docker.io/arangodb/arangodb:3.8.7
- docker.io/arangodb/arangodb:3.9.3
- docker.io/arangodb/arangodb-preview:3.10-nightly
- docker.io/arangodb/arangodb-preview:3.10.0-beta.1
- docker.io/arangodb/enterprise:3.8.7
- docker.io/arangodb/enterprise:3.9.3
- docker.io/arangodb/enterprise-preview:3.10-nightly
- docker.io/arangodb/enterprise-preview:3.10.0-beta.1
topology:
- single
- cluster
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/arangodb/entity/arangosearch/CollectionLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ public class CollectionLink {
private Boolean trackListPositions;
private StoreValuesType storeValues;
private final Collection<FieldLink> fields;
private final Collection<FieldLink> nested;

private CollectionLink(final String name) {
super();
this.name = name;
fields = new ArrayList<>();
nested = new ArrayList<>();
analyzers = new ArrayList<>();
}

Expand Down Expand Up @@ -100,6 +102,16 @@ public CollectionLink fields(final FieldLink... fields) {
return this;
}

/**
* @param nested A list of nested fields
* @return link
* @since ArangoDB 3.10
*/
public CollectionLink nested(final FieldLink... nested) {
this.nested.addAll(Arrays.asList(nested));
return this;
}

public String getName() {
return name;
}
Expand All @@ -124,4 +136,8 @@ public Collection<FieldLink> getFields() {
return fields;
}

public Collection<FieldLink> getNested() {
return nested;
}

}
15 changes: 15 additions & 0 deletions src/main/java/com/arangodb/entity/arangosearch/FieldLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ public class FieldLink {
private Boolean trackListPositions;
private StoreValuesType storeValues;
private final Collection<FieldLink> fields;
private final Collection<FieldLink> nested;

private FieldLink(final String name) {
super();
this.name = name;
fields = new ArrayList<>();
nested = new ArrayList<>();
analyzers = new ArrayList<>();
}

Expand Down Expand Up @@ -77,6 +79,16 @@ public FieldLink fields(final FieldLink... fields) {
return this;
}

/**
* @param nested A list of nested fields
* @return link
* @since ArangoDB 3.10
*/
public FieldLink nested(final FieldLink... nested) {
this.nested.addAll(Arrays.asList(nested));
return this;
}

public String getName() {
return name;
}
Expand All @@ -101,4 +113,7 @@ public Collection<FieldLink> getFields() {
return fields;
}

public Collection<FieldLink> getNested() {
return nested;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ public class VPackDeserializers {
link.fields(deserializeField(fieldsIterator.next()));
}
}
final VPackSlice nested = value.get("nested");
if (nested.isObject()) {
final Iterator<Entry<String, VPackSlice>> fieldsIterator = nested.objectIterator();
while (fieldsIterator.hasNext()) {
link.nested(deserializeField(fieldsIterator.next()));
}
}
properties.addLink(link);
}
}
Expand Down Expand Up @@ -284,6 +291,13 @@ protected static FieldLink deserializeField(final Entry<String, VPackSlice> fiel
link.fields(deserializeField(fieldsIterator.next()));
}
}
final VPackSlice nested = value.get("nested");
if (nested.isObject()) {
final Iterator<Entry<String, VPackSlice>> fieldsIterator = nested.objectIterator();
while (fieldsIterator.hasNext()) {
link.nested(deserializeField(fieldsIterator.next()));
}
}
return link;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ public class VPackSerializers {
builder.add("storeValues", storeValues.name().toLowerCase(Locale.ENGLISH));
}
serializeFieldLinks(builder, collectionLink.getFields());
serializeNested(builder, collectionLink.getNested());
builder.close();
}
builder.close();
Expand Down Expand Up @@ -229,31 +230,44 @@ public class VPackSerializers {
private static void serializeFieldLinks(final VPackBuilder builder, final Collection<FieldLink> links) {
if (!links.isEmpty()) {
builder.add("fields", ValueType.OBJECT);
for (final FieldLink fieldLink : links) {
builder.add(fieldLink.getName(), ValueType.OBJECT);
final Collection<String> analyzers = fieldLink.getAnalyzers();
if (!analyzers.isEmpty()) {
builder.add("analyzers", ValueType.ARRAY);
for (final String analyzer : analyzers) {
builder.add(analyzer);
}
builder.close();
}
final Boolean includeAllFields = fieldLink.getIncludeAllFields();
if (includeAllFields != null) {
builder.add("includeAllFields", includeAllFields);
}
final Boolean trackListPositions = fieldLink.getTrackListPositions();
if (trackListPositions != null) {
builder.add("trackListPositions", trackListPositions);
}
final StoreValuesType storeValues = fieldLink.getStoreValues();
if (storeValues != null) {
builder.add("storeValues", storeValues.name().toLowerCase(Locale.ENGLISH));
serializeFields(builder, links);
builder.close();
}
}

private static void serializeNested(final VPackBuilder builder, final Collection<FieldLink> nested) {
if (!nested.isEmpty()) {
builder.add("nested", ValueType.OBJECT);
serializeFields(builder, nested);
builder.close();
}
}

private static void serializeFields(final VPackBuilder builder, final Collection<FieldLink> links){
for (final FieldLink fieldLink : links) {
builder.add(fieldLink.getName(), ValueType.OBJECT);
final Collection<String> analyzers = fieldLink.getAnalyzers();
if (!analyzers.isEmpty()) {
builder.add("analyzers", ValueType.ARRAY);
for (final String analyzer : analyzers) {
builder.add(analyzer);
}
serializeFieldLinks(builder, fieldLink.getFields());
builder.close();
}
final Boolean includeAllFields = fieldLink.getIncludeAllFields();
if (includeAllFields != null) {
builder.add("includeAllFields", includeAllFields);
}
final Boolean trackListPositions = fieldLink.getTrackListPositions();
if (trackListPositions != null) {
builder.add("trackListPositions", trackListPositions);
}
final StoreValuesType storeValues = fieldLink.getStoreValues();
if (storeValues != null) {
builder.add("storeValues", storeValues.name().toLowerCase(Locale.ENGLISH));
}
serializeFieldLinks(builder, fieldLink.getFields());
serializeNested(builder, fieldLink.getNested());
builder.close();
}
}
Expand Down
53 changes: 34 additions & 19 deletions src/test/java/com/arangodb/ArangoSearchTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -754,19 +754,20 @@ void enhancedTextAnalyzerTyped(ArangoDatabase db) {
void arangoSearchOptions(ArangoDatabase db) {
assumeTrue(isAtLeastVersion(3, 4));
String viewName = "view-" + rnd();
ArangoSearchCreateOptions options = new ArangoSearchCreateOptions()
.link(
CollectionLink.on(COLL_1)
.analyzers("identity")
.fields(
FieldLink.on("id")
.analyzers("identity")
)
.includeAllFields(true)
.storeValues(StoreValuesType.ID)
.trackListPositions(false)

);
FieldLink field = FieldLink.on("f1");
if (isEnterprise()) {
field.nested(FieldLink.on("f2"));
}
CollectionLink link = CollectionLink.on(COLL_1)
.analyzers("identity")
.fields(field)
.includeAllFields(true)
.storeValues(StoreValuesType.ID)
.trackListPositions(false);
if (isEnterprise()) {
link.nested(FieldLink.on("f3"));
}
ArangoSearchCreateOptions options = new ArangoSearchCreateOptions().link(link);

final ArangoSearch view = db.arangoSearch(viewName);
view.create(options);
Expand All @@ -776,13 +777,27 @@ void arangoSearchOptions(ArangoDatabase db) {
assertThat(properties.getId()).isNotNull();
assertThat(properties.getName()).isEqualTo(viewName);
assertThat(properties.getType()).isEqualTo(ViewType.ARANGO_SEARCH);
assertThat(properties.getLinks()).isNotEmpty();

CollectionLink createdLink = properties.getLinks().iterator().next();
assertThat(createdLink.getName()).isEqualTo(COLL_1);
assertThat(createdLink.getAnalyzers()).contains("identity");
assertThat(createdLink.getIncludeAllFields()).isTrue();
assertThat(createdLink.getStoreValues()).isEqualTo(StoreValuesType.ID);
assertThat(createdLink.getTrackListPositions()).isFalse();
if (isEnterprise() && isAtLeastVersion(3, 10)) {
assertThat(createdLink.getNested()).isNotEmpty();
FieldLink nested = createdLink.getNested().iterator().next();
assertThat(nested.getName()).isEqualTo("f3");
}

CollectionLink link = properties.getLinks().iterator().next();
assertThat(link.getAnalyzers()).contains("identity");
assertThat(link.getName()).isEqualTo(COLL_1);
assertThat(link.getIncludeAllFields()).isTrue();
assertThat(link.getStoreValues()).isEqualTo(StoreValuesType.ID);
assertThat(link.getTrackListPositions()).isFalse();
FieldLink fieldLink = createdLink.getFields().iterator().next();
assertThat(fieldLink.getName()).isEqualTo("f1");
if (isEnterprise() && isAtLeastVersion(3, 10)) {
assertThat(fieldLink.getNested()).isNotEmpty();
FieldLink nested = fieldLink.getNested().iterator().next();
assertThat(nested.getName()).isEqualTo("f2");
}
}

@ParameterizedTest(name = "{index}")
Expand Down