[Groonga-commit] ranguba/rroonga at 60e42db [master] Support drilldown by multiple keys

Back to archive index

Masafumi Yokoyama null+****@clear*****
Fri Feb 13 19:12:34 JST 2015


Masafumi Yokoyama	2015-02-13 19:12:34 +0900 (Fri, 13 Feb 2015)

  New Revision: 60e42dbdd9c2de6a7536aa77c7927d027f9fc104
  https://github.com/ranguba/rroonga/commit/60e42dbdd9c2de6a7536aa77c7927d027f9fc104

  Message:
    Support drilldown by multiple keys
    
    GitHub: fix #46

  Modified files:
    ext/groonga/rb-grn-table.c
    test/test-table-group.rb

  Modified: ext/groonga/rb-grn-table.c (+47 -30)
===================================================================
--- ext/groonga/rb-grn-table.c    2015-02-13 14:19:34 +0900 (7c28d07)
+++ ext/groonga/rb-grn-table.c    2015-02-13 19:12:34 +0900 (ac11edb)
@@ -1,7 +1,7 @@
 /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
+  Copyright (C) 2014-2015  Masafumi Yokoyama <yokoyama �� clear-code.com>
   Copyright (C) 2009-2014  Kouhei Sutou <kou �� clear-code.com>
-  Copyright (C) 2014  Masafumi Yokoyama <myokoym �� gmail.com>
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -1306,8 +1306,33 @@ rb_grn_table_sort (int argc, VALUE *argv, VALUE self)
  * 値でグループ化する。多くの場合、キーにはカラムを指定する。
  * カラムはカラム名(文字列)でも指定可能。
  *
+ * If one key is specified, you can get the grouping key by {Groonga::Record#key}:
+ *
+ * <pre>
+ * !!!ruby
+ * grouped_record = table.group("key1").collect do |record|
+ *   [record.key, record.n_sub_records]
+ * end
+ * </pre>
+ *
+ * If two or more keys are specified, the default value of _:max_n_sub_records_
+ * is _1_ (When one key is specified, the value is _0_.). You can get the grouping
+ * keys by {Groonga::Record#sub_records}:
+ *
+ * <pre>
+ * !!!ruby
+ * grouped_record = table.group(["key1", "key2"]).collect do |record|
+ *   sub_record = record.sub_records.first
+ *   [
+ *     sub_record.key1,
+ *     sub_record.key2,
+ *     record.n_sub_records,
+ *   ]
+ * end
+ * </pre>
+ *
  * @overload group([key1, key2, ...], options={})
- *   @return [[Groonga::Hash, ...]]
+ *   @return [Groonga::Hash]
  * @overload group(key, options={})
  *   @return [Groonga::Hash]
  * @option options :max_n_sub_records
@@ -1320,13 +1345,12 @@ rb_grn_table_group (int argc, VALUE *argv, VALUE self)
     grn_ctx *context = NULL;
     grn_obj *table;
     grn_table_sort_key *keys;
-    grn_table_group_result *results;
-    int i, n_keys, n_results;
+    grn_table_group_result result;
+    int i, n_keys;
     unsigned int max_n_sub_records = 0;
     grn_rc rc;
     VALUE rb_keys, rb_options, rb_max_n_sub_records;
     VALUE *rb_group_keys;
-    VALUE rb_results;
 
     rb_grn_table_deconstruct(SELF(self), &table, &context,
                              NULL, NULL,
@@ -1347,8 +1371,15 @@ rb_grn_table_group (int argc, VALUE *argv, VALUE self)
                         "max_n_sub_records", &rb_max_n_sub_records,
                         NULL);
 
-    if (!NIL_P(rb_max_n_sub_records))
+    if (NIL_P(rb_max_n_sub_records)) {
+        if (n_keys > 1) {
+            max_n_sub_records = 1;
+        } else {
+            max_n_sub_records = 0;
+        }
+    } else {
         max_n_sub_records = NUM2UINT(rb_max_n_sub_records);
+    }
 
     keys = ALLOCA_N(grn_table_sort_key, n_keys);
     for (i = 0; i < n_keys; i++) {
@@ -1380,34 +1411,20 @@ rb_grn_table_group (int argc, VALUE *argv, VALUE self)
         keys[i].flags = 0;
     }
 
-    n_results = n_keys;
-    results = ALLOCA_N(grn_table_group_result, n_results);
-    rb_results = rb_ary_new();
-    for (i = 0; i < n_results; i++) {
-        grn_obj *result;
-        VALUE rb_result;
-
-        result = grn_table_create_for_group(context, NULL, 0, NULL,
-                                            keys[i].key, table, max_n_sub_records);
-        results[i].table = result;
-        results[i].key_begin = 0;
-        results[i].key_end = 0;
-        results[i].limit = 0;
-        results[i].flags = 0;
-        results[i].op = GRN_OP_OR;
-
-        rb_result = GRNOBJECT2RVAL(Qnil, context, result, GRN_TRUE);
-        rb_ary_push(rb_results, rb_result);
-    }
+    result.table = NULL;
+    result.key_begin = 0;
+    result.key_end = n_keys - 1;
+    result.limit = 1;
+    result.flags = GRN_TABLE_GROUP_CALC_COUNT;
+    result.op = GRN_OP_OR;
+    result.max_n_subrecs = max_n_sub_records;
+    result.calc_target = NULL;
 
-    rc = grn_table_group(context, table, keys, n_keys, results, n_results);
+    rc = grn_table_group(context, table, keys, n_keys, &result, 1);
     rb_grn_context_check(context, self);
     rb_grn_rc_check(rc, self);
 
-    if (n_results == 1)
-        return rb_ary_pop(rb_results);
-    else
-        return rb_results;
+    return GRNOBJECT2RVAL(Qnil, context, result.table, GRN_TRUE);
 }
 
 /*

  Modified: test/test-table-group.rb (+52 -0)
===================================================================
--- test/test-table-group.rb    2015-02-13 14:19:34 +0900 (34e8a7a)
+++ test/test-table-group.rb    2015-02-13 19:12:34 +0900 (6fc51fe)
@@ -198,4 +198,56 @@ class TableGroupTest < Test::Unit::TestCase
       end
     end
   end
+
+  class MultipleKeyTest < self
+    setup
+    def setup_schema
+      Groonga::Schema.define do |schema|
+        schema.create_table("Memos", :type => :hash) do |table|
+          table.short_text("tag")
+          table.int64("priority")
+        end
+      end
+    end
+
+    setup
+    def setup_data
+      setup_memos
+    end
+
+    def setup_memos
+      @memos = Groonga["Memos"]
+      @memo1 =****@memos*****("Groonga1",
+                          :tag => "Groonga",
+                          :priority => 10)
+      @memo2 =****@memos*****("Groonga2",
+                          :tag => "Groonga",
+                          :priority => 20)
+      @memo3 =****@memos*****("Mroonga1",
+                          :tag => "Mroonga",
+                          :priority => 10)
+      @memo4 =****@memos*****("Mroonga2",
+                          :tag => "Mroonga",
+                          :priority => 10)
+    end
+
+    def test_two_keys
+      keys = ["tag", "priority"]
+      grouped_records =****@memos*****(keys).collect do |record|
+        sub_record = record.sub_records.first
+        [
+          record.n_sub_records,
+          sub_record.tag,
+          sub_record.priority,
+        ]
+      end
+
+      assert_equal([
+                     [1, "Groonga", 10],
+                     [1, "Groonga", 20],
+                     [2, "Mroonga", 10],
+                   ],
+                   grouped_records)
+    end
+  end
 end
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index