/var/log/messages

Jul 20, 2018 - 2 minute read - Comments - Recommendation Ruby

Recommendation 取得実装について

以下コメントのデータを投入して Ruby からデータ要求する実装を確認してみました。

上記の記載で使用したものが以下となります。

gremlin> g.V().has('person','name','alice').as('her').
               out('bought').aggregate('self').
               in('bought').where(neq('her')).
               out('bought').where(without('self')).
               groupCount().
               order(local).
                 by(values, decr)
==>[v[10]:6,v[26]:5,v[12]:5,v[24]:4,v[28]:2]

とりあえず、curl にて取得を行なってみています。

$ curl -X POST -d '{"gremlin": "g.V().has(\"person\",\"name\",\"alice\").as(\"her\").out(\"bought\").aggregate(\"self\").in(\"bought\").where(neq(\"her\")).out(\"bought\").where(without(\"self\")).groupCount().order(local).by(values,decr)"}' http://localhost:8182

取得できた情報は以下となります (整形済み)

{"requestId":"1a3dad8d-d3b7-40a8-aa0e-941cc7efffbe",
 "status":{"message":"","code":200,"attributes":{"@type":"g:Map","@value":[]}},
 "result":
  {"data":
   {"@type":"g:List",
    "@value":[{"@type":"g:Map",
               "@value":
                [{"@type":"g:Vertex",
                  "@value":{"id":{"@type":"g:Int64","@value":9},
                  	        "label":"product",
                  	        "properties":{"name":[{"@type":"g:VertexProperty",
                  	                      "@value":{"id":{"@type":"g:Int64","@value":-1048458284},
                  	                                "value":"product 1",
                  	                                "label":"name"}}]}}},
                 {"@type":"g:Int64","@value":6},
                 {"@type":"g:Vertex",
                  "@value":{"id":{"@type":"g:Int64","@value":17},
                            "label":"product",
                            "properties":{"name":[{"@type":"g:VertexProperty",
                                          "@value":{"id":{"@type":"g:Int64","@value":-1048458268},
                                                    "value":"product 9",
                                                    "label":"name"}}]}}},
                 {"@type":"g:Int64","@value":5},
                 {"@type":"g:Vertex",
                  "@value":{"id":{"@type":"g:Int64","@value":10},
                            "label":"product",
                            "properties":{"name":[{"@type":"g:VertexProperty",
                                          "@value":{"id":{"@type":"g:Int64","@value":-1048458282},
                                                    "value":"product 2",
                                                    "label":"name"}}]}}},
                 {"@type":"g:Int64","@value":5},
                 {"@type":"g:Vertex",
                  "@value":{"id":{"@type":"g:Int64","@value":16},
                            "label":"product",
                            "properties":{"name":[{"@type":"g:VertexProperty",
                                          "@value":{"id":{"@type":"g:Int64","@value":-1048458270},
                                                    "value":"product 8",
                                                    "label":"name"}}]}}},
                 {"@type":"g:Int64","@value":4},
                 {"@type":"g:Vertex",
                  "@value":{"id":{"@type":"g:Int64","@value":18},
                            "label":"product",
                            "properties":{"name":[{"@type":"g:VertexProperty",
                                          "@value":{"id":{"@type":"g:Int64","@value":1756320141},
                                          "value":"product 10",
                                          "label":"name"}}]}}},
                 {"@type":"g:Int64","@value":2}]}]},
    "meta":{"@type":"g:Map","@value":[]}}}

Ruby 実装

同じものを以下の Ruby スクリプトにて取得できていることを確認しています。

require 'net/https'
require 'uri'
require 'json'

    uri = URI.parse("http://localhost:8182/")
    http = Net::HTTP.new(uri.host, uri.port)

    print "uri.host: " + uri.host + "\n"
    print "uri.port: " + uri.port.to_s + "\n"
    print "uri.path: " + uri.path + "\n"

#    http.use_ssl = true
#    http.verify_mode = OpenSSL::SSL::VERIFY_NONE

    req = Net::HTTP::Post.new(uri.path)

    req["Content-Type"] = "application/json"
    xxx = {'gremlin' => 'g.V().has("person","name","alice").as("her").out("bought").aggregate("self").in("bought").where(neq("her")).out("bought").where(without("self")).groupCount().order(local).by(values, decr)'}

    payload = xxx.to_json

    req.body = payload
    res = http.request(req)

#	print "code -> #{res.code} \n"
#	print "msg -> #{res.message} \n"
	print "body -> #{res.body} \n\"
	api_response = JSON.parse(res.body)
	print "response array size -> #{api_response['result']['data']['@value'][0]['@value'].size} \n"
	res_array = api_response['result']['data']['@value'][0]['@value']
	# repeat
	res_array.each do |test|
		print "test -> #{test} \n"
	end

上記スクリプトの出力を以下に引用します。

uri.host: localhost
uri.port: 8182
uri.path: /
response array size -> 10 
test -> {"@type"=>"g:Vertex", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>9}, "label"=>"product", "properties"=>{"name"=>[{"@type"=>"g:VertexProperty", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>-1048458284}, "value"=>"product 1", "label"=>"name"}}]}}} 
test -> {"@type"=>"g:Int64", "@value"=>6} 
test -> {"@type"=>"g:Vertex", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>17}, "label"=>"product", "properties"=>{"name"=>[{"@type"=>"g:VertexProperty", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>-1048458268}, "value"=>"product 9", "label"=>"name"}}]}}} 
test -> {"@type"=>"g:Int64", "@value"=>5} 
test -> {"@type"=>"g:Vertex", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>10}, "label"=>"product", "properties"=>{"name"=>[{"@type"=>"g:VertexProperty", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>-1048458282}, "value"=>"product 2", "label"=>"name"}}]}}} 
test -> {"@type"=>"g:Int64", "@value"=>5} 
test -> {"@type"=>"g:Vertex", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>16}, "label"=>"product", "properties"=>{"name"=>[{"@type"=>"g:VertexProperty", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>-1048458270}, "value"=>"product 8", "label"=>"name"}}]}}} 
test -> {"@type"=>"g:Int64", "@value"=>4} 
test -> {"@type"=>"g:Vertex", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>18}, "label"=>"product", "properties"=>{"name"=>[{"@type"=>"g:VertexProperty", "@value"=>{"id"=>{"@type"=>"g:Int64", "@value"=>1756320141}, "value"=>"product 10", "label"=>"name"}}]}}} 
test -> {"@type"=>"g:Int64", "@value"=>2} 

レスポンスのパースについて

Gremlin の REST Client なライブラリがいくつか Python にありましたので内容確認していますが、response body を走査するものはありませんでした。 そういった意味では以下な @type 要素についてクラスを作って値や属性にアクセスする必要があると思われます。

  • g:Int64
  • g:Vertex (おそらく g:Edge もあると思われます)
  • g:List
  • g:Map
  • g:VertexProperty (おそらく g:EdgeProperty もあると思われます)

上記について特徴を以下に列挙しておきます。

  • g:List の場合、@value が配列 (size で要素数はわかるはず)
  • g:Int64 の場合、@value に値が格納
  • g:Map の場合 @value は配列となっており、偶数要素にキー、奇数要素に値が格納されている模様
  • g:Vertex の場合、@value にはオブジェクト要素が Hash として格納

また、今回のケースでは res['result']['data']['@value'][0] に以下が格納されていると認識しています。

[v[10]:6,v[26]:5,v[12]:5,v[24]:4,v[28]:2]

仕事で始める機械学習 (1) Debian Copyright

comments powered by Disqus