Skip to content

Commit

Permalink
Pass travel timestamp and guarantee timestamp for query/search interf…
Browse files Browse the repository at this point in the history
…ace (#249)

Signed-off-by: yhmo <[email protected]>
  • Loading branch information
yhmo authored Jan 18, 2022
1 parent 4d6fb11 commit 0b7176b
Show file tree
Hide file tree
Showing 12 changed files with 231 additions and 15 deletions.
14 changes: 13 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
# Changelog
# Changelog

## milvus-sdk-java 2.0.1 (2021-01-18)

### Improvement

- \#248 - Pass travel timestamp and guarantee timestamp for query/search interface

## milvus-sdk-java 2.0.0 (2021-12-31)

### Feature

- \#183 - java sdk for milvus 2.0

## milvus-sdk-java 0.8.5 (2020-08-26)

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The following table shows compatibilities between Milvus and Java SDK.

| Milvus version | Java SDK version |
| :------------: | :--------------: |
| 2.0 | 2.0.0 |
| 2.0 | 2.0.1 |

### Install Java SDK

Expand All @@ -27,14 +27,14 @@ You can use **Apache Maven** or **Gradle**/**Grails** to download the SDK.
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.0.0</version>
<version>2.0.1</version>
</dependency>
```

- Gradle/Grails

```gradle
compile 'io.milvus:milvus-sdk-java:2.0.0'
compile 'io.milvus:milvus-sdk-java:2.0.1'
```

### Examples
Expand Down
15 changes: 13 additions & 2 deletions examples/main/io/milvus/GeneralExample.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private void handleResponseStatus(R<?> r) {
}
}

private R<RpcStatus> createCollection(long timeoutMiliseconds) {
private R<RpcStatus> createCollection(long timeoutMilliseconds) {
System.out.println("========== createCollection() ==========");
FieldType fieldType1 = FieldType.newBuilder()
.withName(ID_FIELD)
Expand Down Expand Up @@ -109,7 +109,7 @@ private R<RpcStatus> createCollection(long timeoutMiliseconds) {
.addFieldType(fieldType3)
// .addFieldType(fieldType4)
.build();
R<RpcStatus> response = milvusClient.withTimeout(timeoutMiliseconds, TimeUnit.MILLISECONDS)
R<RpcStatus> response = milvusClient.withTimeout(timeoutMilliseconds, TimeUnit.MILLISECONDS)
.createCollection(createCollectionReq);
handleResponseStatus(response);
System.out.println(response);
Expand Down Expand Up @@ -315,6 +315,7 @@ private R<MutationResult> delete(String partitionName, String expr) {

private R<SearchResults> searchFace(String expr) {
System.out.println("========== searchFace() ==========");
long begin = System.currentTimeMillis();

List<String> outFields = Collections.singletonList(AGE_FIELD);
List<List<Float>> vectors = generateFloatVectors(5);
Expand All @@ -328,9 +329,14 @@ private R<SearchResults> searchFace(String expr) {
.withVectorFieldName(VECTOR_FIELD)
.withExpr(expr)
.withParams(SEARCH_PARAM)
.withGuaranteeTimestamp(Constant.GUARANTEE_EVENTUALLY_TS)
.build();

R<SearchResults> response = milvusClient.search(searchParam);
long end = System.currentTimeMillis();
long cost = (end - begin);
System.out.println("Search time cost: " + cost + "ms");

handleResponseStatus(response);
SearchResultsWrapper wrapper = new SearchResultsWrapper(response.getData().getResults());
for (int i = 0; i < vectors.size(); ++i) {
Expand All @@ -346,6 +352,7 @@ private R<SearchResults> searchFace(String expr) {

// private R<SearchResults> searchProfile(String expr) {
// System.out.println("========== searchProfile() ==========");
// long begin = System.currentTimeMillis();
//
// List<String> outFields = Collections.singletonList(AGE_FIELD);
// List<ByteBuffer> vectors = generateBinaryVectors(5);
Expand All @@ -363,6 +370,10 @@ private R<SearchResults> searchFace(String expr) {
//
//
// R<SearchResults> response = milvusClient.search(searchParam);
// long end = System.currentTimeMillis();
// long cost = (end - begin);
// System.out.println("Search time cost: " + cost + "ms");
//
// handleResponseStatus(response);
// SearchResultsWrapper wrapper = new SearchResultsWrapper(response.getData().getResults());
// for (int i = 0; i < vectors.size(); ++i) {
Expand Down
4 changes: 2 additions & 2 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java-examples</artifactId>
<version>2.0.0</version>
<version>2.0.1</version>
<build>
<plugins>
<plugin>
Expand Down Expand Up @@ -63,7 +63,7 @@
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.0.0</version>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.0.0</version>
<version>2.0.1</version>
<packaging>jar</packaging>

<name>io.milvus:milvus-sdk-java</name>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/io/milvus/Response/MutationResultWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,16 @@ public List<String> getStringIDs() throws ParamException {
public long getDeleteCount() {
return result.getDeleteCnt();
}

/**
* Get timestamp of the operation marked by server. You can use this timestamp as for guarantee timestamp of query/search api.
*
* Note: the timestamp is not an absolute timestamp, it is a hybrid value combined by UTC time and internal flags.
* We call it TSO, for more information please refer to: https://github.com/milvus-io/milvus/blob/master/docs/design_docs/milvus_hybrid_ts_en.md
*
* @return <code>int</code> row count of the deleted entities
*/
public long getOperationTs() {
return result.getTimestamp();
}
}
5 changes: 5 additions & 0 deletions src/main/java/io/milvus/client/AbstractMilvusGrpcClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,9 @@ public R<SearchResults> search(@NonNull SearchParam requestParam) {
builder.setDsl(requestParam.getExpr());
}

builder.setTravelTimestamp(requestParam.getTravelTimestamp());
builder.setGuaranteeTimestamp(requestParam.getGuaranteeTimestamp());

SearchRequest searchRequest = builder.build();
SearchResults response = this.blockingStub().search(searchRequest);

Expand Down Expand Up @@ -1499,6 +1502,8 @@ public R<QueryResults> query(@NonNull QueryParam requestParam) {
.addAllPartitionNames(requestParam.getPartitionNames())
.addAllOutputFields(requestParam.getOutFields())
.setExpr(requestParam.getExpr())
.setTravelTimestamp(requestParam.getTravelTimestamp())
.setGuaranteeTimestamp(requestParam.getGuaranteeTimestamp())
.build();

QueryResults response = this.blockingStub().query(queryRequest);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/io/milvus/param/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,13 @@ public class Constant {

// max value for waiting create index interval, unit: millisecond
public static final Long MAX_WAITING_INDEX_INTERVAL = 2000L;


// set this value for "withGuaranteeTimestamp" of QueryParam/SearchParam
// to instruct server execute query/search immediately.
public static final Long GUARANTEE_EVENTUALLY_TS = 1L;

// set this value for "withGuaranteeTimestamp" of QueryParam/SearchParam
// to instruct server execute query/search after all DML operations finished.
public static final Long GUARANTEE_STRONG_TS = 0L;
}
46 changes: 46 additions & 0 deletions src/main/java/io/milvus/param/dml/QueryParam.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.google.common.collect.Lists;
import io.milvus.exception.ParamException;
import io.milvus.param.Constant;
import io.milvus.param.ParamUtils;
import lombok.Getter;
import lombok.NonNull;
Expand All @@ -37,12 +38,16 @@ public class QueryParam {
private final List<String> partitionNames;
private final List<String> outFields;
private final String expr;
private final long travelTimestamp;
private final long guaranteeTimestamp;

private QueryParam(@NonNull Builder builder) {
this.collectionName = builder.collectionName;
this.partitionNames = builder.partitionNames;
this.outFields = builder.outFields;
this.expr = builder.expr;
this.travelTimestamp = builder.travelTimestamp;
this.guaranteeTimestamp = builder.guaranteeTimestamp;
}

public static Builder newBuilder() {
Expand All @@ -57,6 +62,8 @@ public static class Builder {
private final List<String> partitionNames = Lists.newArrayList();
private final List<String> outFields = new ArrayList<>();
private String expr = "";
private Long travelTimestamp = 0L;
private Long guaranteeTimestamp = Constant.GUARANTEE_EVENTUALLY_TS;

private Builder() {
}
Expand Down Expand Up @@ -132,6 +139,37 @@ public Builder withExpr(@NonNull String expr) {
return this;
}

/**
* Specify an absolute timestamp in a query to get results based on a data view at a specified point in time.
* Default value is 0, server executes query on a full data view.
*
* @param ts a timestamp value
* @return <code>Builder</code>
*/
public Builder withTravelTimestamp(@NonNull Long ts) {
this.travelTimestamp = ts;
return this;
}

/**
* Instructs server to see insert/delete operations performed before a provided timestamp.
* If no such timestamp is specified, the server will wait for the latest operation to finish and query.
*
* Note: The timestamp is not an absolute timestamp, it is a hybrid value combined by UTC time and internal flags.
* We call it TSO, for more information please refer to: https://github.com/milvus-io/milvus/blob/master/docs/design_docs/milvus_hybrid_ts_en.md
* You can get a TSO from insert/delete operations, see the <code>MutationResultWrapper</code> class.
* Use an operation's TSO to set this parameter, the server will execute query after this operation is finished.
*
* Default value is GUARANTEE_EVENTUALLY_TS, query executes query immediately.
*
* @param ts a timestamp value
* @return <code>Builder</code>
*/
public Builder withGuaranteeTimestamp(@NonNull Long ts) {
this.guaranteeTimestamp = ts;
return this;
}

/**
* Verifies parameters and creates a new <code>QueryParam</code> instance.
*
Expand All @@ -141,6 +179,14 @@ public QueryParam build() throws ParamException {
ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
ParamUtils.CheckNullEmptyString(expr, "Expression");

if (travelTimestamp < 0) {
throw new ParamException("The travel timestamp must be greater than 0");
}

if (guaranteeTimestamp < 0) {
throw new ParamException("The guarantee timestamp must be greater than 0");
}

return new QueryParam(this);
}
}
Expand Down
51 changes: 48 additions & 3 deletions src/main/java/io/milvus/param/dml/SearchParam.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@

import com.google.common.collect.Lists;
import io.milvus.exception.ParamException;
import io.milvus.param.Constant;
import io.milvus.param.MetricType;
import io.milvus.param.ParamUtils;

import lombok.Getter;
import lombok.NonNull;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -45,6 +45,8 @@ public class SearchParam {
private final List<?> vectors;
private final int roundDecimal;
private final String params;
private final long travelTimestamp;
private final long guaranteeTimestamp;

private SearchParam(@NonNull Builder builder) {
this.collectionName = builder.collectionName;
Expand All @@ -57,6 +59,8 @@ private SearchParam(@NonNull Builder builder) {
this.vectors = builder.vectors;
this.roundDecimal = builder.roundDecimal;
this.params = builder.params;
this.travelTimestamp = builder.travelTimestamp;
this.guaranteeTimestamp = builder.guaranteeTimestamp;
}

public static Builder newBuilder() {
Expand All @@ -73,10 +77,12 @@ public static class Builder {
private String vectorFieldName;
private Integer topK;
private String expr = "";
private List<String> outFields = new ArrayList<>();
private final List<String> outFields = Lists.newArrayList();
private List<?> vectors;
private Integer roundDecimal = -1;
private String params = "{}";
private Long travelTimestamp = 0L;
private Long guaranteeTimestamp = Constant.GUARANTEE_EVENTUALLY_TS;

Builder() {
}
Expand Down Expand Up @@ -168,7 +174,7 @@ public Builder withExpr(@NonNull String expr) {
* @return <code>Builder</code>
*/
public Builder withOutFields(@NonNull List<String> outFields) {
this.outFields = outFields;
outFields.forEach(this::addOutField);
return this;
}

Expand Down Expand Up @@ -223,6 +229,37 @@ public Builder withParams(@NonNull String params) {
return this;
}

/**
* Specify an absolute timestamp in a search to get results based on a data view at a specified point in time.
* Default value is 0, server executes search on a full data view.
*
* @param ts a timestamp value
* @return <code>Builder</code>
*/
public Builder withTravelTimestamp(@NonNull Long ts) {
this.travelTimestamp = ts;
return this;
}

/**
* Instructs server to see insert/delete operations performed before a provided timestamp.
* If no such timestamp is specified, the server will wait for the latest operation to finish and search.
*
* Note: The timestamp is not an absolute timestamp, it is a hybrid value combined by UTC time and internal flags.
* We call it TSO, for more information please refer to: https://github.com/milvus-io/milvus/blob/master/docs/design_docs/milvus_hybrid_ts_en.md
* You can get a TSO from insert/delete operations, see the <code>MutationResultWrapper</code> class.
* Use an operation's TSO to set this parameter, the server will execute search after this operation is finished.
*
* Default value is GUARANTEE_EVENTUALLY_TS, server executes search immediately.
*
* @param ts a timestamp value
* @return <code>Builder</code>
*/
public Builder withGuaranteeTimestamp(@NonNull Long ts) {
this.guaranteeTimestamp = ts;
return this;
}

/**
* Verifies parameters and creates a new <code>SearchParam</code> instance.
*
Expand All @@ -236,6 +273,14 @@ public SearchParam build() throws ParamException {
throw new ParamException("TopK value is illegal");
}

if (travelTimestamp < 0) {
throw new ParamException("The travel timestamp must be greater than 0");
}

if (guaranteeTimestamp < 0) {
throw new ParamException("The guarantee timestamp must be greater than 0");
}

if (metricType == MetricType.INVALID) {
throw new ParamException("Metric type is illegal");
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/milvus/param/index/CreateIndexParam.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public CreateIndexParam build() throws ParamException {
}
}

ParamUtils.CheckNullEmptyString(extraParam, "Index extra param");
// ParamUtils.CheckNullEmptyString(extraParam, "Index extra param");

return new CreateIndexParam(this);
}
Expand Down
Loading

0 comments on commit 0b7176b

Please sign in to comment.