'Method Not Found' During UDF QueryAggregateCall

aggregation
udf
error

#1

I’m trying to run an aggregation from C# code but I’m facing a very strange error:

Aerospike.Client.AerospikeException Query Failed: Method not found: ‘Neo.IronLua.LuaGlobal Neo.IronLua.Lua.CreateEnvironment()’.

Let me start saying that from AQL the aggregation is working fine as you guys can see at: https://cloud.githubusercontent.com/assets/938045/17008830/772dbd8c-4ecb-11e6-84e6-b0585dadcdda.png

So let me put here same of my code so you guys can help me to identity how can I fix this error

` LuaConfig.PackagePath = “/opt/aerospike/usr/udf/lua”; //LuaConfig.PackagePath = “c://”;

var statement = new Statement(); statement.SetNamespace(“audit”); statement.SetSetName(“year2016”); statement.SetFilters(new Filter[] { Filter.Equal(“application”, “availability”) });

var resultSet = AerospikeAuditClient.QueryAggregate(null, statement, “audit_filters”, “filterBySubject”, Value.Get(“321”)); `

Also let me set here the lua udf that I’m calling above

` local function filter_subject(subject) return function(rec) if rec[‘subject’] and (type(rec[‘subject’]) == ‘string’) and rec[‘subject’] == subject then return true end return false end end

local function map_profile(record) return map {application=record.application, subject=record.subject} end

function filterBySubject(stream, subject) return stream : filter(filter_subject(subject)) : map(map_profile) end`

Please any advise to fix this will be great …


Can't run QueryAggregate from client
#2

I wrote a complete program on Windows from your code and it returns the same info as AQL. I suspect there is a problem opening “audit_filters.lua” on clients running in mono on Linux (I don’t have a test environment for this configuration).

The lua functions are run on both server and client (final reduce) for aggregation queries. “audit_filters.lua” must be readable from the client machine. “audit_filters.lua” does not need to be shared with the server. I recommend keeping “audit_filters.lua” in a separate client directory from the server, so there is no contention when reading the file.

I still would like to know if AerospikeDemo QuerySum works for you?


Set HOST and LUA_DIR variables and place “audit_filters.lua” in your LUA_DIR directory.

using System;
using System.IO;
using System.Collections;
using System.Text;
using Aerospike.Client;

namespace AggregationTest
{
    class AggregationTest
    {
        private const string HOST = "bn66";
        private const string LUA_DIR = "C:/Users/bnichols/udf/";

        static void Main(string[] args)
        {
            try
            {
                Log.SetCallback(Logger);
                LuaConfig.PackagePath = LUA_DIR + "?.lua";
                AerospikeClient client = new AerospikeClient(null, HOST, 3000);

                try
                {
                    RunTest(client);
                }
                finally
                {
                    client.Close();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.StackTrace);
            }
        }

        private static void RunTest(AerospikeClient client)
        {
            string packageName = "audit_filters.lua";

            RegisterTask rt = client.Register(null, LUA_DIR + packageName, packageName, Language.LUA);
            rt.Wait();
 
            IndexTask it = client.CreateIndex(null, "audit", "year2016", "appindex", "application", IndexType.STRING);
            it.Wait();

            client.Put(null, new Key("audit", "year2016", 1), new Bin("application", "aaaaaaaaaaaa"), new Bin("subject", "111"));
            client.Put(null, new Key("audit", "year2016", 2), new Bin("application", "availability"), new Bin("subject", "222"));
            client.Put(null, new Key("audit", "year2016", 3), new Bin("application", "availability"), new Bin("subject", "321"));
            client.Put(null, new Key("audit", "year2016", 4), new Bin("application", "availability"), new Bin("subject", "321"));
            client.Put(null, new Key("audit", "year2016", 5), new Bin("application", "bbbbbbbbbbbb"), new Bin("subject", "321"));

            var statement = new Statement();
            statement.SetNamespace("audit");
            statement.SetSetName("year2016");
            statement.SetFilters(new Filter[] { Filter.Equal("application", "availability") });

            var resultSet = client.QueryAggregate(null, statement, "audit_filters", "filterBySubject", Value.Get("321"));

            try
            {
                while (resultSet.Next())
                {
                    object obj = resultSet.Object;

                    if (obj is IDictionary)
                    {
                        Console.WriteLine(MapToString((IDictionary)obj));
                    }
                    else
                    {
                        Console.WriteLine(obj.ToString());
                    }
                }
            }
            finally
            {
                resultSet.Close();
            }

            client.DropIndex(null, "audit", "year2016", "appindex");
        }

        private static string MapToString(IDictionary map)
        {
            StringBuilder sb = new StringBuilder(200);
            MapToString(sb, map);
            return sb.ToString();
        }

        private static void MapToString(StringBuilder sb, IDictionary map)
        {
            sb.Append('[');
            int i = 0;

            foreach (DictionaryEntry entry in map)
            {
                if (i > 0)
                {
                    sb.Append(", ");
                }
                sb.Append('{');

                sb.Append(entry.Key);
                sb.Append(",");
                sb.Append(entry.Value);
                sb.Append('}');
                i++;
            }
            sb.Append(']');
        }

        private static void Logger(Log.Level level, string message)
        {
            Console.WriteLine(level.ToString() + ':' + message);
        }
    }
}

#3

Hi Brian, thanks for your anwsers but I’m still facing same issue.

Indeed I just downloaded aerospike-sample-applications from grithub and ran the C# application. I can see that data is written ok (https://cloud.githubusercontent.com/assets/938045/17113221/0dc42b8e-5280-11e6-84c8-ab488d579837.png) but the applications fails when run option 7 that uses aggregagtion (https://cloud.githubusercontent.com/assets/938045/17113235/1ed574be-5280-11e6-8466-0e5ae3dcccde.png)


#4

Running AerospikeDemo at aerospike-client-csharp github project it’s working fine !!


#5

@Brian, After several tests I think I found the issue.

It’s look like that it doesn’t work on Asp .Net … all my tests on Console and Windows Application worked fine but when moving same code to Asp .Net project it’s fail again

Do you have tried to run AerospikeDemo on Asp .Net project??


#6

No. Our examples/tests do not use ASP.NET.

I suspect there is a problem reading files from the filesystem in ASP.NET. I recommend placing the lua files in resources in the DLL itself. The lua test files in the AerospikeTest project are stored as resources. Make sure each lua file “Properties” -> “Build Action” is changed to “Embedded Resource”.

The aggregration query call would then look something like this:

            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);