milvus-io / milvus

A cloud-native vector database, storage for next generation AI applications
https://milvus.io
Apache License 2.0
29.49k stars 2.83k forks source link

[Bug]: query expr not match result return error code empty collection #21007

Closed yelusion2 closed 1 year ago

yelusion2 commented 1 year ago

Is there an existing issue for this?

Environment

- Milvus version: 2.2
- Deployment mode(standalone or cluster):standalone
- SDK version(e.g. pymilvus v2.0.0rc2): 
- OS(Ubuntu or CentOS): 
- CPU/Memory: 
- GPU: 
- Others:

Current Behavior

1.create a collection(test collection), include a varchar field(like testvarchar). 2.insert some date. 3.query data (like timestamp >= "1670307439")

query expr not match result return : empty collection or improper expression

Expected Behavior

query expr not match result null :

Steps To Reproduce

1.create a collection(test collection), include a varchar field(like testvarchar).
2.insert some date.
3.query data(like  timestamp >= "1670307439")

Milvus Log

No response

Anything else?

No response

yelusion2 commented 1 year ago

example code: import io.milvus.client.MilvusServiceClient; import io.milvus.grpc.DataType; import io.milvus.grpc.DescribeCollectionResponse; import io.milvus.grpc.DescribeIndexResponse; import io.milvus.grpc.GetCollectionStatisticsResponse; import io.milvus.grpc.GetImportStateResponse; import io.milvus.grpc.GetIndexBuildProgressResponse; import io.milvus.grpc.GetIndexStateResponse; import io.milvus.grpc.ImportResponse; import io.milvus.grpc.ManualCompactionResponse; import io.milvus.grpc.MutationResult; import io.milvus.grpc.QueryResults; import io.milvus.grpc.SearchResults; import io.milvus.grpc.ShowCollectionsResponse; import io.milvus.grpc.ShowPartitionsResponse; import io.milvus.param.ConnectParam; import io.milvus.param.Constant; import io.milvus.param.IndexType; import io.milvus.param.MetricType; import io.milvus.param.R; import io.milvus.param.RpcStatus; import io.milvus.param.bulkinsert.BulkInsertParam; import io.milvus.param.bulkinsert.GetBulkInsertStateParam; import io.milvus.param.collection.CreateCollectionParam; import io.milvus.param.collection.DescribeCollectionParam; import io.milvus.param.collection.DropCollectionParam; import io.milvus.param.collection.FieldType; import io.milvus.param.collection.GetCollectionStatisticsParam; import io.milvus.param.collection.HasCollectionParam; import io.milvus.param.collection.LoadCollectionParam; import io.milvus.param.collection.ReleaseCollectionParam; import io.milvus.param.collection.ShowCollectionsParam; import io.milvus.param.control.ManualCompactParam; import io.milvus.param.dml.DeleteParam; import io.milvus.param.dml.InsertParam; import io.milvus.param.dml.QueryParam; import io.milvus.param.dml.SearchParam; import io.milvus.param.index.CreateIndexParam; import io.milvus.param.index.DescribeIndexParam; import io.milvus.param.index.DropIndexParam; import io.milvus.param.index.GetIndexBuildProgressParam; import io.milvus.param.index.GetIndexStateParam; import io.milvus.param.partition.CreatePartitionParam; import io.milvus.param.partition.DropPartitionParam; import io.milvus.param.partition.HasPartitionParam; import io.milvus.param.partition.ReleasePartitionsParam; import io.milvus.param.partition.ShowPartitionsParam; import io.milvus.response.DescCollResponseWrapper; import io.milvus.response.GetCollStatResponseWrapper; import io.milvus.response.MutationResultWrapper; import io.milvus.response.QueryResultsWrapper;

import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit;

public class Test1 { private static MilvusServiceClient milvusClient;

private static void init(String uri, String userName, String password){
    ConnectParam connectParam = ConnectParam.newBuilder()
            .withUri(uri)
            .withAuthorization(userName,password)
            .build();
    milvusClient = new MilvusServiceClient(connectParam);
}

private static final String ID_FIELD = "userID";
private static final String VECTOR_FIELD = "userFace";
private static final Integer VECTOR_DIM = 256;
private static final String AGE_FIELD = "timestamp";

// private static final String PROFILE_FIELD = "userProfile"; // private static final Integer BINARY_DIM = 128;

private static final String INDEX_NAME = "userFaceIndex";
private static final IndexType INDEX_TYPE = IndexType.IVF_FLAT;
private static final String INDEX_PARAM = "{\"nlist\":128}";

private static final Integer SEARCH_K = 5;
private static final String SEARCH_PARAM = "{\"nprobe\":10}";

private void handleResponseStatus(R<?> r) {
    if (r.getStatus() != R.Status.Success.getCode()) {
        throw new RuntimeException(r.getMessage());
    }
}

private R<RpcStatus> createCollection(String collection, long timeoutMilliseconds) {
    System.out.println("========== createCollection() ==========");
    FieldType fieldType1 = FieldType.newBuilder()
            .withName(ID_FIELD)
            .withDescription("test auto id")
            .withDataType(DataType.Int64)
            .withPrimaryKey(true)
            .withAutoID(true)
            .build();

    FieldType fieldType2 = FieldType.newBuilder()
            .withName(VECTOR_FIELD)
            .withDescription("test vectors")
            .withDataType(DataType.FloatVector)
            .withDimension(VECTOR_DIM)
            .build();

    FieldType fieldType3 = FieldType.newBuilder()
            .withName(AGE_FIELD)
            .withDescription("time stamp")
            .withDataType(DataType.VarChar)
            .withMaxLength(64)
            .build();

    CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder()
            .withCollectionName(collection)
            .withDescription("test collection")
            .withShardsNum(2)
            .addFieldType(fieldType1)
            .addFieldType(fieldType2)
            .addFieldType(fieldType3)

// .addFieldType(fieldType4) .build(); R response = milvusClient.withTimeout(timeoutMilliseconds, TimeUnit.MILLISECONDS) .createCollection(createCollectionReq); handleResponseStatus(response); return response; }

private R<RpcStatus> dropCollection(String collection) {
    System.out.println("========== dropCollection() ==========");
    R<RpcStatus> response = milvusClient.dropCollection(DropCollectionParam.newBuilder()
            .withCollectionName(collection)
            .build());
    return response;
}

private boolean hasCollection(String collection) {
    System.out.println("========== hasCollection() ==========");
    R<Boolean> response = milvusClient.hasCollection(HasCollectionParam.newBuilder()
            .withCollectionName(collection)
            .build());
    handleResponseStatus(response);
    return response.getData().booleanValue();
}

private R<RpcStatus> loadCollection(String collection) {
    System.out.println("========== loadCollection() ==========");
    R<RpcStatus> response = milvusClient.loadCollection(LoadCollectionParam.newBuilder()
            .withCollectionName(collection)
            .build());
    handleResponseStatus(response);
    return response;
}

private R<RpcStatus> getBucketInsert() {
    System.out.println("========== loadCollection() ==========");
    R<GetImportStateResponse> response = milvusClient.getBulkInsertState(GetBulkInsertStateParam.newBuilder()
            .withTask(437223996748424900L)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return null;
}
private R<RpcStatus> bucketInsert() {
    System.out.println("========== loadCollection() ==========");
    R<ImportResponse> response = milvusClient.bulkInsert(BulkInsertParam.newBuilder()
            .withCollectionName("test2")
            .addFile("bulkload/in01-551f1fc11f92de5/floatVectorField.npy")
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return null;
}

private R<RpcStatus> releaseCollection(String collection) {
    System.out.println("========== releaseCollection() ==========");
    R<RpcStatus> response = milvusClient.releaseCollection(ReleaseCollectionParam.newBuilder()
            .withCollectionName(collection)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<DescribeCollectionResponse> describeCollection(String collection) {
    System.out.println("========== describeCollection() ==========");
    R<DescribeCollectionResponse> response = milvusClient.describeCollection(DescribeCollectionParam.newBuilder()
            .withCollectionName(collection)
            .build());
    handleResponseStatus(response);
    DescCollResponseWrapper wrapper = new DescCollResponseWrapper(response.getData());
    return response;
}

private R<GetCollectionStatisticsResponse> getCollectionStatistics(String collection) {
    System.out.println("========== getCollectionStatistics() ==========");
    R<GetCollectionStatisticsResponse> response = milvusClient.getCollectionStatistics(
            GetCollectionStatisticsParam.newBuilder()
                    .withCollectionName(collection)
                    .build());
    handleResponseStatus(response);
    GetCollStatResponseWrapper wrapper = new GetCollStatResponseWrapper(response.getData());
    System.out.println("Collection row count: " + wrapper.getRowCount());
    return response;
}

private R<ShowCollectionsResponse> showCollections() {
    System.out.println("========== showCollections() ==========");
    R<ShowCollectionsResponse> response = milvusClient.showCollections(ShowCollectionsParam.newBuilder()
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<RpcStatus> createPartition(String collection,String partitionName) {
    System.out.println("========== createPartition() ==========");
    R<RpcStatus> response = milvusClient.createPartition(CreatePartitionParam.newBuilder()
            .withCollectionName(collection)
            .withPartitionName(partitionName)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<RpcStatus> dropPartition(String collection, String partitionName) {
    System.out.println("========== dropPartition() ==========");
    R<RpcStatus> response = milvusClient.dropPartition(DropPartitionParam.newBuilder()
            .withCollectionName(collection)
            .withPartitionName(partitionName)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<Boolean> hasPartition(String collection, String partitionName) {
    System.out.println("========== hasPartition() ==========");
    R<Boolean> response = milvusClient.hasPartition(HasPartitionParam.newBuilder()
            .withCollectionName(collection)
            .withPartitionName(partitionName)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<RpcStatus> releasePartition(String collection, String partitionName) {
    System.out.println("========== releasePartition() ==========");
    R<RpcStatus> response = milvusClient.releasePartitions(ReleasePartitionsParam.newBuilder()
            .withCollectionName(collection)
            .addPartitionName(partitionName)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<ShowPartitionsResponse> showPartitions(String collection) {
    System.out.println("========== showPartitions() ==========");
    R<ShowPartitionsResponse> response = milvusClient.showPartitions(ShowPartitionsParam.newBuilder()
            .withCollectionName(collection)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<RpcStatus> createIndex(String collection) {
    System.out.println("========== createIndex() ==========");
    R<RpcStatus> response = milvusClient.createIndex(CreateIndexParam.newBuilder()
            .withCollectionName(collection)
            .withFieldName(VECTOR_FIELD)
            .withIndexName(INDEX_NAME)
            .withIndexType(IndexType.AUTOINDEX)
            .withMetricType(MetricType.L2)
            .withExtraParam(INDEX_PARAM)
            .withSyncMode(Boolean.TRUE)
            .build());
    handleResponseStatus(response);
    return response;
}

private R<RpcStatus> dropIndex(String collection) {
    System.out.println("========== dropIndex() ==========");
    R<RpcStatus> response = milvusClient.dropIndex(DropIndexParam.newBuilder()
            .withCollectionName(collection)
            .withIndexName(INDEX_NAME)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<DescribeIndexResponse> describeIndex(String collection) {
    System.out.println("========== describeIndex() ==========");
    R<DescribeIndexResponse> response = milvusClient.describeIndex(DescribeIndexParam.newBuilder()
            .withCollectionName(collection)
            .withIndexName(INDEX_NAME)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<GetIndexStateResponse> getIndexState(String collection) {
    System.out.println("========== getIndexState() ==========");
    R<GetIndexStateResponse> response = milvusClient.getIndexState(GetIndexStateParam.newBuilder()
            .withCollectionName(collection)
            .withIndexName(INDEX_NAME)
            .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<GetIndexBuildProgressResponse> getIndexBuildProgress(String collection) {
    System.out.println("========== getIndexBuildProgress() ==========");
    R<GetIndexBuildProgressResponse> response = milvusClient.getIndexBuildProgress(
            GetIndexBuildProgressParam.newBuilder()
                    .withCollectionName(collection)
                    .withIndexName(INDEX_NAME)
                    .build());
    handleResponseStatus(response);
    System.out.println(response);
    return response;
}

private R<MutationResult> delete(String collection,String partitionName, String expr) {
    System.out.println("========== delete() ==========");
    DeleteParam build = DeleteParam.newBuilder()
            .withCollectionName(collection)
            .withPartitionName(partitionName)
            .withExpr(expr)
            .build();
    R<MutationResult> response = milvusClient.delete(build);
    handleResponseStatus(response);
    return response;
}

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

    List<String> outFields = Collections.singletonList(AGE_FIELD);
    List<List<Float>> vectors = generateFloatVectors(5);

    SearchParam searchParam = SearchParam.newBuilder()
            .withCollectionName(collection)
            .withMetricType(MetricType.L2)
            .withOutFields(outFields)
            .withTopK(SEARCH_K)
            .withVectors(vectors)
            .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");

    return response;
}

// private R searchProfile(String expr) { // System.out.println("========== searchProfile() =========="); // long begin = System.currentTimeMillis(); // // List outFields = Collections.singletonList(AGE_FIELD); // List vectors = generateBinaryVectors(5); // // SearchParam searchParam = SearchParam.newBuilder() // .withCollectionName(COLLECTION_NAME) // .withMetricType(MetricType.HAMMING) // .withOutFields(outFields) // .withTopK(SEARCH_K) // .withVectors(vectors) // .withVectorFieldName(PROFILE_FIELD) // .withExpr(expr) // .withParams(SEARCH_PARAM) // .build(); // // // R 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) { // System.out.println("Search result of No." + i); // List scores = wrapper.getIDScore(i); // System.out.println(scores); // System.out.println("Output field data for No." + i); // System.out.println(wrapper.getFieldData(AGE_FIELD, i)); // } // // return response; // }

private R<QueryResults> query(String collection,String expr) {
    System.out.println("========== query() ==========");
    List<String> fields = Arrays.asList(ID_FIELD, AGE_FIELD);
    QueryParam test = QueryParam.newBuilder()
            .withCollectionName(collection)
            .withExpr(expr)
            .withOutFields(fields)
            .build();
    R<QueryResults> response = milvusClient.query(test);
    handleResponseStatus(response);
    QueryResultsWrapper wrapper = new QueryResultsWrapper(response.getData());
    System.out.println(ID_FIELD + ":" + wrapper.getFieldWrapper(ID_FIELD).getFieldData().toString());
    System.out.println(AGE_FIELD + ":" + wrapper.getFieldWrapper(AGE_FIELD).getFieldData().toString());
    System.out.println("Query row count: " + wrapper.getFieldWrapper(ID_FIELD).getRowCount());
    return response;
}

private R<ManualCompactionResponse> compact(String collection) {
    System.out.println("========== compact() ==========");
    R<ManualCompactionResponse> response = milvusClient.manualCompact(ManualCompactParam.newBuilder()
            .withCollectionName(collection)
            .build());
    handleResponseStatus(response);
    return response;
}

public R<MutationResult> insert(String collection, String partitionName, int count) {
    List<List<Float>> vectors = generateFloatVectors(count);

// List profiles = generateBinaryVectors(count);

    List<String> ages = new ArrayList<>();
    for (long i = 0L; i < count; ++i) {
        ages.add(System.currentTimeMillis()+"");
    }

    List<InsertParam.Field> fields = new ArrayList<>();
    fields.add(new InsertParam.Field(AGE_FIELD, ages));
    fields.add(new InsertParam.Field(VECTOR_FIELD, vectors));

// fields.add(new InsertParam.Field(PROFILE_FIELD, profiles));

    InsertParam insertParam = InsertParam.newBuilder()
            .withCollectionName(collection)
            .withPartitionName(partitionName)
            .withFields(fields)
            .build();

    R<MutationResult> response = milvusClient.insert(insertParam);
    handleResponseStatus(response);
    return response;
}

private List<List<Float>> generateFloatVectors(int count) {
    Random ran = new Random();
    List<List<Float>> vectors = new ArrayList<>();
    for (int n = 0; n < count; ++n) {
        List<Float> vector = new ArrayList<>();
        for (int i = 0; i < VECTOR_DIM; ++i) {
            vector.add(ran.nextFloat());
        }
        vectors.add(vector);
    }

    return vectors;
}

public static void main(String[] args) throws InterruptedException {
    init("","","");
    Test1 example = new Test1();
    example.getCollectionStatistics("yelusion6");
    example.query("yelusion6", " timestamp <= \"0\"");

// String uri = System.getProperty("uri"); // String user = System.getProperty("user"); // String password = System.getProperty("password"); // String collection = System.getProperty("collection"); // init(uri, user, password); // // Test1 example = new Test1(); // // if (example.hasCollection(collection)) { // example.dropCollection(collection); // } // example.createCollection(collection,2000); // example.hasCollection(collection); // example.describeCollection(collection); // example.showCollections(); // example.createIndex(collection); // example.loadCollection(collection); // // final String partitionName = "p1"; // example.createPartition(collection,partitionName); // example.hasPartition(collection,partitionName); // example.showPartitions(collection); // // for(int i=0; i<10000; i++){ // Thread.sleep(100); // R result = example.insert(collection, partitionName, 10000); // } // // example.getCollectionStatistics(collection); } }

class MyThread extends Thread{ private Test1 example; private String collection; private String partitionName; public MyThread() { }

public MyThread(Test1 example,String collection, String partitionName) {
    this.example = example;
    this.collection = collection;
    this.partitionName = partitionName;
}

@Override
public void run() {
    final int row_count = 10000;
    for (int i = 0; i < 100; ++i) {
        R<MutationResult> result = example.insert(collection, partitionName, row_count);
    }
}

}

longjiquan commented 1 year ago

/unassign @yanliang567 /assign

longjiquan commented 1 year ago

https://github.com/milvus-io/pymilvus/blob/d705ee37592c39901efc8e0896a13e530e66a7b1/pymilvus/client/grpc_handler.py#L881-L882

longjiquan commented 1 year ago

image

longjiquan commented 1 year ago

Already fixed in #21066 and #21066 .

longjiquan commented 1 year ago

/assign @yelusion2 @yhmo

yanliang567 commented 1 year ago

@yelusion2 could you please help to verify the fix on milvus 2.2.1?

yelusion2 commented 1 year ago

image Fixed in milvus 2.2.2, Great Job.