public void QueryFilter()
        {
            string nameFilter = "Bill";
            string passFilter = "hknfpkj";

            Statement stmt = new Statement();
            stmt.SetNamespace(args.ns);
            stmt.SetSetName(args.set);
            stmt.SetFilters(Filter.Equal(binName, nameFilter));
            stmt.SetAggregateFunction(Assembly.GetExecutingAssembly(), "Aerospike.Test.Resources.filter_example.lua", "filter_example", "profile_filter", Value.Get(passFilter));

            // passFilter will be applied in filter_example.lua.
            ResultSet rs = client.QueryAggregate(null, stmt);

            try
            {
                int count = 0;

                while (rs.Next())
                {
                    IDictionary map = (IDictionary)rs.Object;
                    Assert.AreEqual(nameFilter, map["name"]);
                    Assert.AreEqual(passFilter, map["password"]);
                    count++;
                }
                Assert.AreNotEqual(0, count);
            }
            finally
            {
                rs.Close();
            }
        }
        public void QuerySum()
        {
            int begin = 4;
            int end = 7;

            Statement stmt = new Statement();
            stmt.SetNamespace(args.ns);
            stmt.SetSetName(args.set);
            stmt.SetBinNames(binName);
            stmt.SetFilters(Filter.Range(binName, begin, end));
            stmt.SetAggregateFunction(Assembly.GetExecutingAssembly(), "Aerospike.Test.Resources.sum_example.lua", "sum_example", "sum_single_bin", Value.Get(binName));

            ResultSet rs = client.QueryAggregate(null, stmt);

            try
            {
                int expected = 22; // 4 + 5 + 6 + 7
                int count = 0;

                while (rs.Next())
                {
                    object obj = rs.Object;
                    long sum = 0;

                    if (obj is long)
                    {
                        sum = (long)rs.Object;
                    }
                    else
                    {
                        Assert.Fail("Return value not a long: " + obj);
                    }
                    Assert.AreEqual(expected, (int)sum);
                    count++;
                }
                Assert.AreNotEqual(0, count);
            }
            finally
            {
                rs.Close();
            }
        }
        public void QueryAverage()
        {
            Statement stmt = new Statement();
            stmt.SetNamespace(args.ns);
            stmt.SetSetName(args.set);
            stmt.SetFilters(Filter.Range(binName, 0, 1000));
            stmt.SetAggregateFunction(Assembly.GetExecutingAssembly(), "Aerospike.Test.Resources.average_example.lua", "average_example", "average");

            ResultSet rs = client.QueryAggregate(null, stmt);

            try
            {
                if (rs.Next())
                {
                    object obj = rs.Object;

                    if (obj is IDictionary)
                    {
                        IDictionary map = (IDictionary)obj;
                        long sum = (long)map["sum"];
                        long count = (long)map["count"];
                        double avg = (double) sum / count;
                        Assert.AreEqual(5.5, avg, 0.00000001);
                    }
                    else
                    {
                        Assert.Fail("Unexpected object returned: " + obj);
                    }
                }
                else
                {
                    Assert.Fail("Query Assert.Failed. No records returned.");
                }
            }
            finally
            {
                rs.Close();
            }
        }
        private void RunQuery(AerospikeClient client, Arguments args, string indexName, string binName)
        {
            string nameFilter = "Bill";
            string passFilter = "hknfpkj";

            console.Info("Query for: ns=%s set=%s index=%s name=%s pass=%s", args.ns, args.set, indexName, nameFilter, passFilter);

            Statement stmt = new Statement();
            stmt.SetNamespace(args.ns);
            stmt.SetSetName(args.set);
            stmt.SetFilters(Filter.Equal(binName, nameFilter));
            stmt.SetAggregateFunction("filter_example", "profile_filter", Value.Get(passFilter));

            // passFilter will be applied in filter_example.lua.
            ResultSet rs = client.QueryAggregate(null, stmt);

            try
            {
                int count = 0;

                while (rs.Next())
                {
                    Dictionary<object, object> map = (Dictionary<object, object>)rs.Object;
                    Validate(map, "name", nameFilter);
                    Validate(map, "password", passFilter);
                    count++;
                }

                if (count == 0)
                {
                    console.Error("Query failed. No records returned.");
                }
            }
            finally
            {
                rs.Close();
            }
        }
        public KeyRecordEnumerator Select(Statement stmt, bool metaOnly, params Qualifier[] qualifiers)
        {
            KeyRecordEnumerator results = null;
            /*
             * no filters
             */
            if (qualifiers == null || qualifiers.Length == 0)  {
                RecordSet recordSet = this.client.Query(null, stmt);
                results = new KeyRecordEnumerator(stmt.Namespace, recordSet);
                return results;
            }
            /*
             * singleton using primary key
             */
            if (qualifiers != null && qualifiers.Length == 1 && qualifiers[0] is KeyQualifier)  {
                KeyQualifier kq = (KeyQualifier)qualifiers[0];
                Key key = kq.MakeKey(stmt.Namespace, stmt.SetName);
                //System.out.println(key);
                Record record = null;
                if (metaOnly)
                    record = this.client.GetHeader(null, key);
                else
                    record = this.client.Get(null, key, stmt.BinNames);
                if (record == null){
                    results = new KeyRecordEnumerator(stmt.Namespace);
                } else {
                    KeyRecord keyRecord = new KeyRecord(key, record);
                    results = new KeyRecordEnumerator(stmt.Namespace, keyRecord);
                }
                return results;
            }
            /*
             *  query with filters
             */
            Dictionary<String, Object> originArgs = new Dictionary<String, Object>();
            originArgs["includeAllFields"] = 1;

            for (int i = 0; i < qualifiers.Length; i++){
                Qualifier qualifier = qualifiers[i];
                if (isIndexedBin(qualifier)){
                    Filter filter = qualifier.AsFilter();
                    if (filter != null){
                        stmt.Filters = new Filter[] { filter };
                        qualifiers[i] = null;
                        break;
                    }
                }
            }

            String filterFuncStr = buildFilterFunction(qualifiers);
            originArgs["filterFuncStr"] = filterFuncStr;
            Value argValue = Value.Get (originArgs);
            String fnName = "";

            if (metaOnly)
                fnName = "query_meta";
            else
                fnName = "select_records";

            stmt.SetAggregateFunction(
                Assembly.GetExecutingAssembly(),
                "Aerospike.Helper.udf."+ QUERY_MODULE + ".lua",
                QUERY_MODULE,
                fnName,
                argValue);

            ResultSet resultSet = this.client.QueryAggregate(null, stmt);
            results = new KeyRecordEnumerator(stmt.Namespace, resultSet);
            return results;
        }
        public KeyRecordEnumerator Select(Statement stmt, IDictionary<String, String> sortMap, params Qualifier[] qualifiers)
        {
            KeyRecordEnumerator results = null;

            if (qualifiers != null && qualifiers.Length > 0) {
                IDictionary<String, Object> originArgs = new Dictionary<String, Object>();
                originArgs["includeAllFields"] = 1;
                string filterFuncStr = buildFilterFunction(qualifiers);
                originArgs["filterFuncStr"] = filterFuncStr;
                string sortFuncStr = buildSortFunction(sortMap);
                originArgs["sortFuncStr"] = sortFuncStr;
                stmt.SetAggregateFunction(QUERY_MODULE, "select_records", Value.Get(originArgs));
                ResultSet resultSet = this.client.QueryAggregate(null, stmt);
                results = new KeyRecordEnumerator(stmt.Namespace, resultSet);
            } else {
                RecordSet recordSet = this.client.Query(null, stmt);
                results = new KeyRecordEnumerator(stmt.Namespace, recordSet);
            }
            return results;
        }
        //----------------------------------------------------------
        // Query/Execute UDF (Supported by Aerospike 3 servers only)
        //----------------------------------------------------------
        /// <summary>
        /// Apply user defined function on records that match the statement filter.
        /// Records are not returned to the client.
        /// This asynchronous server call will return before command is complete.  
        /// The user can optionally wait for command completion by using the returned 
        /// ExecuteTask instance.
        /// <para>
        /// This method is only supported by Aerospike 3 servers.
        /// </para>
        /// </summary>
        /// <param name="policy">configuration parameters, pass in null for defaults</param>
        /// <param name="statement">record filter</param>
        /// <param name="packageName">server package where user defined function resides</param>
        /// <param name="functionName">function name</param>
        /// <param name="functionArgs">to pass to function name, if any</param>
        /// <exception cref="AerospikeException">if command fails</exception>
        public ExecuteTask Execute(WritePolicy policy, Statement statement, string packageName, string functionName, params Value[] functionArgs)
        {
            if (policy == null)
            {
                policy = writePolicyDefault;
            }

            statement.SetAggregateFunction(packageName, functionName, functionArgs);
            statement.Prepare(false);

            Node[] nodes = cluster.Nodes;
            if (nodes.Length == 0)
            {
                throw new AerospikeException(ResultCode.SERVER_NOT_AVAILABLE, "Command failed because cluster is empty.");
            }

            Executor executor = new Executor(nodes.Length);

            foreach (Node node in nodes)
            {
                ServerCommand command = new ServerCommand(node, policy, statement);
                executor.AddCommand(command);
            }

            executor.Execute(nodes.Length);
            return new ExecuteTask(cluster, policy, statement);
        }
 /// <summary>
 /// Execute query, apply statement's aggregation function, and return result iterator. 
 /// The aggregation function should be located in a Lua script file that can be found from the 
 /// "LuaConfig.PackagePath" paths static variable.  The default package path is "udf/?.lua"
 /// where "?" is the packageName.
 /// <para>
 /// The query executor puts results on a queue in separate threads.  The calling thread 
 /// concurrently pops results off the queue through the ResultSet iterator.
 /// The aggregation function is called on both server and client (final reduce).
 /// Therefore, the Lua script file must also reside on both server and client.
 /// </para>
 /// <para>
 /// This method is only supported by Aerospike 3 servers.
 /// </para>
 /// </summary>
 /// <param name="policy">generic configuration parameters, pass in null for defaults</param>
 /// <param name="statement">database query command</param>
 /// <param name="packageName">server package where user defined function resides</param>
 /// <param name="functionName">aggregation function name</param>
 /// <param name="functionArgs">arguments to pass to function name, if any</param>
 /// <exception cref="AerospikeException">if query fails</exception>
 public ResultSet QueryAggregate(QueryPolicy policy, Statement statement, string packageName, string functionName, params Value[] functionArgs)
 {
     statement.SetAggregateFunction(packageName, functionName, functionArgs);
     return QueryAggregate(policy, statement);
 }
        private void RunQuery(AerospikeClient client, Arguments args, string indexName, string binName1, string binName2)
        {
            StringBuilder rgnsb = new StringBuilder();

            rgnsb.Append("{ ");
            rgnsb.Append("    \"type\": \"Polygon\", ");
            rgnsb.Append("    \"coordinates\": [ ");
            rgnsb.Append("        [[-122.500000, 37.000000],[-121.000000, 37.000000], ");
            rgnsb.Append("         [-121.000000, 38.080000],[-122.500000, 38.080000], ");
            rgnsb.Append("         [-122.500000, 37.000000]] ");
            rgnsb.Append("    ] ");
            rgnsb.Append(" } ");

            console.Info("QueryRegion: " + rgnsb);

            string amenStr = "school";

            Statement stmt = new Statement();
            stmt.SetNamespace(args.ns);
            stmt.SetSetName(args.set);
            stmt.SetFilters(Filter.GeoWithinRegion(binName1, rgnsb.ToString()));
            stmt.SetAggregateFunction("geo_filter_example", "match_amenity", Value.Get(amenStr));

            ResultSet rs = client.QueryAggregate(null, stmt);

            try
            {
                int count = 0;

                while (rs.Next())
                {
                    object result = rs.Object;
                    console.Info("Record found: " + result);
                    count++;
                }

                if (count != 2)
                {
                    console.Error("Wrong number of schools found. %d != 2", count);
                }
            }
            finally
            {
                rs.Close();
            }
        }