[Groonga-commit] groonga/groonga [master] Support score respected merge by set operation

アーカイブの一覧に戻る

Kouhei Sutou null+****@clear*****
Wed Sep 5 16:25:25 JST 2012


Kouhei Sutou	2012-09-05 16:25:25 +0900 (Wed, 05 Sep 2012)

  New Revision: 58b1b787c6cbba74e133c8f88fe7e5fe486fbccd
  https://github.com/groonga/groonga/commit/58b1b787c6cbba74e133c8f88fe7e5fe486fbccd

  Merged f2c89a6: Merge pull request #31 from groonga/support-score-respected-merge-by-set-operation

  Log:
    Support score respected merge by set operation
    
    --filter '(A || B) && C &! D' assign 3 (A + B + C) as score
    when a record that matches A, B and C.
    --filter '(A || B) && (C &! D)' assign 2 (A + B) as score
    when a record that matches A, B and C.
    
    Both of them should assign 3 as score. This change fixes the problem.

  Added files:
    test/function/suite/select/score/need_temporary_table/and.expected
    test/function/suite/select/score/need_temporary_table/and.test
    test/function/suite/select/score/need_temporary_table/or.expected
    test/function/suite/select/score/need_temporary_table/or.test
  Modified files:
    lib/db.c

  Modified: lib/db.c (+40 -10)
===================================================================
--- lib/db.c    2012-09-04 18:03:26 +0900 (81b7df1)
+++ lib/db.c    2012-09-05 16:25:25 +0900 (065c567)
@@ -3172,6 +3172,7 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *
   void *key = NULL, *value1 = NULL, *value2 = NULL;
   uint32_t value_size = 0;
   uint32_t key_size = 0;
+  grn_bool have_subrec;
   if (table1 != res) {
     if (table2 == res) {
       grn_obj *t = table1;
@@ -3181,6 +3182,8 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *
       return GRN_INVALID_ARGUMENT;
     }
   }
+  have_subrec = ((DB_OBJ(table1)->header.flags & GRN_OBJ_WITH_SUBREC) &&
+                 (DB_OBJ(table2)->header.flags & GRN_OBJ_WITH_SUBREC));
   switch (table1->header.type) {
   case GRN_TABLE_HASH_KEY :
     value_size = ((grn_hash *)table1)->value_size;
@@ -3217,18 +3220,45 @@ grn_table_setoperation(grn_ctx *ctx, grn_obj *table1, grn_obj *table2, grn_obj *
   }
   switch (op) {
   case GRN_OP_OR :
-    GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
-      if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, NULL)) {
-        memcpy(value1, value2, value_size);
-      }
-    });
+    if (have_subrec) {
+      int added;
+      GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+        if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, &added)) {
+          if (added) {
+            memcpy(value1, value2, value_size);
+          } else {
+            grn_rset_recinfo *ri1 = value1;
+            grn_rset_recinfo *ri2 = value2;
+            grn_table_add_subrec_inline(table1, ri1, ri2->score, NULL, 0);
+          }
+        }
+      });
+    } else {
+      GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {
+        if (grn_table_add_v_inline(ctx, table1, key, key_size, &value1, NULL)) {
+          memcpy(value1, value2, value_size);
+        }
+      });
+    }
     break;
   case GRN_OP_AND :
-    GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, {
-      if (!grn_table_get_v(ctx, table2, key, key_size, &value2)) {
-        _grn_table_delete_by_id(ctx, table1, id, NULL);
-      }
-    });
+    if (have_subrec) {
+      GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, {
+        if (grn_table_get_v(ctx, table2, key, key_size, &value2)) {
+          grn_rset_recinfo *ri1 = value1;
+          grn_rset_recinfo *ri2 = value2;
+          ri1->score += ri2->score;
+        } else {
+          _grn_table_delete_by_id(ctx, table1, id, NULL);
+        }
+      });
+    } else {
+      GRN_TABLE_EACH(ctx, table1, 0, 0, id, &key, &key_size, &value1, {
+        if (!grn_table_get_v(ctx, table2, key, key_size, &value2)) {
+          _grn_table_delete_by_id(ctx, table1, id, NULL);
+        }
+      });
+    }
     break;
   case GRN_OP_AND_NOT :
     GRN_TABLE_EACH(ctx, table2, 0, 0, id, &key, &key_size, &value2, {

  Added: test/function/suite/select/score/need_temporary_table/and.expected (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/select/score/need_temporary_table/and.expected    2012-09-05 16:25:25 +0900 (b05d3bb)
@@ -0,0 +1,18 @@
+table_create Tags TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Movies TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Movies tags COLUMN_VECTOR Tags
+[[0,0.0,0.0],true]
+column_create Tags index COLUMN_INDEX Movies tags
+[[0,0.0,0.0],true]
+load --table Movies
+[
+{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Kurosawa Akira"]},
+{"_key": "The Last Samurai", tags: ["Samurai", "English", "Tom Cruise"]},
+{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English"]},
+{"_key": "Star Wars", tags: ["George Lucas", "SF", "English"]}
+]
+[[0,0.0,0.0],4]
+select Movies   --output_columns "_key, _score"   --filter '(tags @ "English" || tags @ "Samurai") && (tags @ "SF" &! tags @ "Keanu Reeves")'
+[[0,0.0,0.0],[[[1],[["_key","ShortText"],["_score","Int32"]],["Star Wars",2]]]]

  Added: test/function/suite/select/score/need_temporary_table/and.test (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/select/score/need_temporary_table/and.test    2012-09-05 16:25:25 +0900 (ecf42ae)
@@ -0,0 +1,18 @@
+table_create Tags TABLE_HASH_KEY ShortText
+
+table_create Movies TABLE_HASH_KEY ShortText
+column_create Movies tags COLUMN_VECTOR Tags
+
+column_create Tags index COLUMN_INDEX Movies tags
+
+load --table Movies
+[
+{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Kurosawa Akira"]},
+{"_key": "The Last Samurai", tags: ["Samurai", "English", "Tom Cruise"]},
+{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English"]},
+{"_key": "Star Wars", tags: ["George Lucas", "SF", "English"]}
+]
+
+select Movies \
+  --output_columns "_key, _score" \
+  --filter '(tags @ "English" || tags @ "Samurai") && (tags @ "SF" &! tags @ "Keanu Reeves")'

  Added: test/function/suite/select/score/need_temporary_table/or.expected (+53 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/select/score/need_temporary_table/or.expected    2012-09-05 16:25:25 +0900 (27d78fb)
@@ -0,0 +1,53 @@
+table_create Tags TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+table_create Movies TABLE_HASH_KEY ShortText
+[[0,0.0,0.0],true]
+column_create Movies tags COLUMN_VECTOR Tags
+[[0,0.0,0.0],true]
+column_create Tags index COLUMN_INDEX Movies tags
+[[0,0.0,0.0],true]
+load --table Movies
+[
+{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Japan", "Kurosawa Akira"]},
+{"_key": "The Last Samurai", tags: ["Samurai", "English", "Japanese", "US", "Japan", "Tom Cruise"]},
+{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English", "US"]},
+{"_key": "Star Wars", tags: ["George Lucas", "SF", "English", "US"]}
+]
+[[0,0.0,0.0],4]
+select Movies   --output_columns "_key, _score"   --filter '(tags @ "English" && tags @ "SF") || (tags @ "US" &! tags @ "Keanu Reeves")'
+[
+  [
+    0,
+    0.0,
+    0.0
+  ],
+  [
+    [
+      [
+        3
+      ],
+      [
+        [
+          "_key",
+          "ShortText"
+        ],
+        [
+          "_score",
+          "Int32"
+        ]
+      ],
+      [
+        "The Last Samurai",
+        1
+      ],
+      [
+        "The Matrix",
+        2
+      ],
+      [
+        "Star Wars",
+        3
+      ]
+    ]
+  ]
+]

  Added: test/function/suite/select/score/need_temporary_table/or.test (+18 -0) 100644
===================================================================
--- /dev/null
+++ test/function/suite/select/score/need_temporary_table/or.test    2012-09-05 16:25:25 +0900 (a913000)
@@ -0,0 +1,18 @@
+table_create Tags TABLE_HASH_KEY ShortText
+
+table_create Movies TABLE_HASH_KEY ShortText
+column_create Movies tags COLUMN_VECTOR Tags
+
+column_create Tags index COLUMN_INDEX Movies tags
+
+load --table Movies
+[
+{"_key": "Seven Samurai", tags: ["Samurai", "Japanese", "Japan", "Kurosawa Akira"]},
+{"_key": "The Last Samurai", tags: ["Samurai", "English", "Japanese", "US", "Japan", "Tom Cruise"]},
+{"_key": "The Matrix", tags: ["Keanu Reeves", "SF", "English", "US"]},
+{"_key": "Star Wars", tags: ["George Lucas", "SF", "English", "US"]}
+]
+
+select Movies \
+  --output_columns "_key, _score" \
+  --filter '(tags @ "English" && tags @ "SF") || (tags @ "US" &! tags @ "Keanu Reeves")'
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る