Kouhei Sutou
null+****@clear*****
Tue Nov 11 18:21:11 JST 2014
Kouhei Sutou 2014-11-11 18:21:11 +0900 (Tue, 11 Nov 2014) New Revision: 5fc0349d1dd51cbb6eb3609703b12ce1323a8f85 https://github.com/groonga/groonga/commit/5fc0349d1dd51cbb6eb3609703b12ce1323a8f85 Message: ii: optimize for small result set (but disabled by default) If result set is small and indexed records are large, searching with index is slower than sequential search. This change uses sequential search for the case. You can custom the behavior by GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO environment variable: * -1: Disable the optimization * other value: Use the optimization if ("# of result set" / "# of indexed records of a term") > GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO The default GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO is -1. It means that the feature is disabled by default. Limitations: * CMake build isn't supported yet. * Support only exact match. Added files: test/command/suite/select/index/match/string/too_many.expected test/command/suite/select/index/match/string/too_many.test Modified files: configure.ac lib/Makefile.am lib/ii.c Modified: configure.ac (+3 -1) =================================================================== --- configure.ac 2014-11-11 17:34:15 +0900 (3838296) +++ configure.ac 2014-11-11 18:21:11 +0900 (274c04d) @@ -1440,7 +1440,6 @@ if test "$enable_mruby" = "yes"; then MRUBY_CFLAGS="-I\$(top_srcdir)/vendor/mruby-source/include" MRUBY_LIBS="\$(top_builddir)/vendor/mruby/libmruby.la" MRUBY_LIBS="${MRUBY_LIBS} \$(top_builddir)/vendor/onigmo-source/libonig.la" - AC_CONFIG_SUBDIRS([vendor/onigmo]) else MRUBY_CFLAGS= MRUBY_LIBS= @@ -1457,6 +1456,9 @@ AC_ARG_ENABLE(shared-onigmo, [enable_shared_onigmo="no"]) AM_CONDITIONAL(WITH_SHARED_ONIGMO, test "$enable_shared_onigmo" = "yes") +AC_DEFINE(GRN_WITH_ONIGMO, [1], [Use Onigmo.]) +AC_CONFIG_SUBDIRS([vendor/onigmo]) + # PCRE GRN_WITH_PCRE=no AC_ARG_WITH(pcre, Modified: lib/Makefile.am (+6 -1) =================================================================== --- lib/Makefile.am 2014-11-11 17:34:15 +0900 (d71ccbd) +++ lib/Makefile.am 2014-11-11 18:21:11 +0900 (760f883) @@ -11,7 +11,12 @@ AM_CFLAGS = \ $(GRN_CFLAGS) \ $(MESSAGE_PACK_CFLAGS) \ $(MRUBY_CFLAGS) -DEFAULT_INCLUDES = -I$(top_builddir) -I$(top_srcdir)/include + +DEFAULT_INCLUDES = \ + -I$(top_builddir) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/vendor/onigmo-source + DEFS += -D_REENTRANT $(GRN_DEFS) -DGRN_DAT_EXPORT include sources.am Modified: lib/ii.c (+222 -0) =================================================================== --- lib/ii.c 2014-11-11 17:34:15 +0900 (b9a8327) +++ lib/ii.c 2014-11-11 18:21:11 +0900 (e342c73) @@ -28,6 +28,15 @@ #include "grn_output.h" #include "grn_util.h" +#ifdef GRN_WITH_ONIGMO +# define GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH +#endif + +#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH +# include "grn_string.h" +# include <oniguruma.h> +#endif + #define MAX_PSEG 0x20000 #define S_CHUNK (1 << GRN_II_W_CHUNK) #define W_SEGMENT 18 @@ -5859,6 +5868,213 @@ grn_ii_term_extract(grn_ctx *ctx, grn_ii *ii, const char *string, return rc; } +#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH +static grn_bool +grn_ii_select_sequential_search_should_use(grn_ctx *ctx, + grn_ii *ii, + const char *raw_query, + unsigned int raw_query_len, + grn_hash *result, + grn_operator op, + grn_wv_mode wvm, + grn_select_optarg *optarg, + token_info **token_infos, + uint32_t n_token_infos, + double too_many_index_match_ratio) +{ + int n_sources; + + if (too_many_index_match_ratio < 0.0) { + return GRN_FALSE; + } + + if (op != GRN_OP_AND) { + return GRN_FALSE; + } + + if (optarg->mode != GRN_OP_EXACT) { + return GRN_FALSE; + } + + n_sources = ii->obj.source_size / sizeof(grn_id); + if (n_sources == 0) { + return GRN_FALSE; + } + + { + uint32_t i; + int n_existing_records; + + n_existing_records = GRN_HASH_SIZE(result); + for (i = 0; i < n_token_infos; i++) { + token_info *info = token_infos[i]; + if (n_existing_records <= (info->size * too_many_index_match_ratio)) { + return GRN_TRUE; + } + } + return GRN_FALSE; + } +} + +static void +grn_ii_select_sequential_search_body(grn_ctx *ctx, + grn_ii *ii, + grn_obj *normalizer, + grn_encoding encoding, + OnigRegex regex, + grn_hash *result, + grn_operator op, + grn_wv_mode wvm, + grn_select_optarg *optarg) +{ + int i, n_sources; + grn_id *source_ids = ii->obj.source; + grn_obj buffer; + + GRN_TEXT_INIT(&buffer, 0); + n_sources = ii->obj.source_size / sizeof(grn_id); + for (i = 0; i < n_sources; i++) { + grn_id source_id = source_ids[i]; + grn_obj *source; + char column_name[GRN_TABLE_MAX_KEY_SIZE]; + int column_name_size; + grn_obj *accessor; + + source = grn_ctx_at(ctx, source_id); + column_name_size = grn_column_name(ctx, source, + column_name, + GRN_TABLE_MAX_KEY_SIZE); + accessor = grn_obj_column(ctx, (grn_obj *)result, column_name, + column_name_size); + { + grn_hash_cursor *cursor; + grn_id id; + cursor = grn_hash_cursor_open(ctx, result, NULL, 0, NULL, 0, 0, -1, 0); + while ((id = grn_hash_cursor_next(ctx, cursor)) != GRN_ID_NIL) { + OnigPosition position; + grn_obj *value; + const char *normalized_value; + unsigned int normalized_value_length; + + GRN_BULK_REWIND(&buffer); + grn_obj_get_value(ctx, accessor, id, &buffer); + value = grn_string_open_(ctx, + GRN_TEXT_VALUE(&buffer), + GRN_TEXT_LEN(&buffer), + normalizer, 0, encoding); + grn_string_get_normalized(ctx, value, + &normalized_value, &normalized_value_length, + NULL); + position = onig_search(regex, + normalized_value, + normalized_value + normalized_value_length, + normalized_value, + normalized_value + normalized_value_length, + NULL, + 0); + if (position != ONIG_MISMATCH) { + grn_rset_posinfo info; + uint32_t score; + info.rid = id; + info.sid = i + 1; + info.pos = 0; + score = get_weight(ctx, result, info.rid, info.sid, wvm, optarg); + res_add(ctx, result, &info, score, op); + } + grn_obj_unlink(ctx, value); + } + grn_hash_cursor_close(ctx, cursor); + } + grn_obj_unlink(ctx, accessor); + } + grn_obj_unlink(ctx, &buffer); +} + +static grn_bool +grn_ii_select_sequential_search(grn_ctx *ctx, + grn_ii *ii, + const char *raw_query, + unsigned int raw_query_len, + grn_hash *result, + grn_operator op, + grn_wv_mode wvm, + grn_select_optarg *optarg, + token_info **token_infos, + uint32_t n_token_infos) +{ + grn_bool processed = GRN_TRUE; + + { + /* Disabled by default. */ + double too_many_index_match_ratio = -1; + const char *too_many_index_match_ratio_env = + getenv("GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO"); + if (too_many_index_match_ratio_env) { + too_many_index_match_ratio = atof(too_many_index_match_ratio_env); + } + + if (!grn_ii_select_sequential_search_should_use(ctx, + ii, + raw_query, + raw_query_len, + result, + op, + wvm, + optarg, + token_infos, + n_token_infos, + too_many_index_match_ratio)) { + return GRN_FALSE; + } + } + + { + grn_encoding encoding; + grn_obj *normalizer; + int nflags = 0; + grn_obj *query; + const char *normalized_query; + unsigned int normalized_query_length; + + grn_table_get_info(ctx, ii->lexicon, + NULL, &encoding, NULL, &normalizer, NULL); + query = grn_string_open_(ctx, raw_query, raw_query_len, + normalizer, nflags, encoding); + grn_string_get_normalized(ctx, query, + &normalized_query, &normalized_query_length, + NULL); + { + OnigRegex regex; + int onig_result; + OnigErrorInfo error_info; + onig_result = onig_new(®ex, + normalized_query, + normalized_query + normalized_query_length, + ONIG_OPTION_NONE, + ONIG_ENCODING_UTF8, + ONIG_SYNTAX_ASIS, + &error_info); + if (onig_result == ONIG_NORMAL) { + grn_ii_select_sequential_search_body(ctx, ii, normalizer, encoding, + regex, result, op, wvm, optarg); + onig_free(regex); + } else { + char message[ONIG_MAX_ERROR_MESSAGE_LEN]; + onig_error_code_to_str(message, onig_result, error_info); + GRN_LOG(ctx, GRN_LOG_WARNING, + "[ii][select][sequential] " + "failed to create regular expression object: %s", + message); + processed = GRN_FALSE; + } + } + grn_obj_unlink(ctx, query); + } + + return processed; +} +#endif + grn_rc grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_len, grn_hash *s, grn_operator op, grn_select_optarg *optarg) @@ -5938,6 +6154,12 @@ grn_ii_select(grn_ctx *ctx, grn_ii *ii, const char *string, unsigned int string_ goto exit; } */ +#ifdef GRN_II_SELECT_ENABLE_SEQUENTIAL_SEARCH + if (grn_ii_select_sequential_search(ctx, ii, string, string_len, + s, op, wvm, optarg, tis, n)) { + goto exit; + } +#endif for (;;) { rid = (*tis)->p->rid; sid = (*tis)->p->sid; Added: test/command/suite/select/index/match/string/too_many.expected (+265 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/index/match/string/too_many.expected 2014-11-11 18:21:11 +0900 (a630cca) @@ -0,0 +1,265 @@ +table_create Logs TABLE_NO_KEY +[[0,0.0,0.0],true] +column_create Logs message COLUMN_SCALAR ShortText +[[0,0.0,0.0],true] +table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto +[[0,0.0,0.0],true] +column_create Terms logs_message COLUMN_INDEX|WITH_SECTION Logs message +[[0,0.0,0.0],true] +load --table Logs +[ +{"message": "Log 1"}, +{"message": "Log 2"}, +{"message": "Log 3"}, +{"message": "Log 4"}, +{"message": "Log 5"}, +{"message": "Log 6"}, +{"message": "Log 7"}, +{"message": "Log 8"}, +{"message": "Log 9"}, +{"message": "Log 10"}, +{"message": "Log 11"}, +{"message": "Log 12"}, +{"message": "Log 13"}, +{"message": "Log 14"}, +{"message": "Log 15"}, +{"message": "Log 16"}, +{"message": "Log 17"}, +{"message": "Log 18"}, +{"message": "Log 19"}, +{"message": "Log 20"}, +{"message": "Log 21"}, +{"message": "Log 22"}, +{"message": "Log 23"}, +{"message": "Log 24"}, +{"message": "Log 25"}, +{"message": "Log 26"}, +{"message": "Log 27"}, +{"message": "Log 28"}, +{"message": "Log 29"}, +{"message": "Log 30"}, +{"message": "Log 31"}, +{"message": "Log 32"}, +{"message": "Log 33"}, +{"message": "Log 34"}, +{"message": "Log 35"}, +{"message": "Log 36"}, +{"message": "Log 37"}, +{"message": "Log 38"}, +{"message": "Log 39"}, +{"message": "Log 40"}, +{"message": "Log 41"}, +{"message": "Log 42"}, +{"message": "Log 43"}, +{"message": "Log 44"}, +{"message": "Log 45"}, +{"message": "Log 46"}, +{"message": "Log 47"}, +{"message": "Log 48"}, +{"message": "Log 49"}, +{"message": "Log 50"}, +{"message": "Log 51"}, +{"message": "Log 52"}, +{"message": "Log 53"}, +{"message": "Log 54"}, +{"message": "Log 55"}, +{"message": "Log 56"}, +{"message": "Log 57"}, +{"message": "Log 58"}, +{"message": "Log 59"}, +{"message": "Log 60"}, +{"message": "Log 61"}, +{"message": "Log 62"}, +{"message": "Log 63"}, +{"message": "Log 64"}, +{"message": "Log 65"}, +{"message": "Log 66"}, +{"message": "Log 67"}, +{"message": "Log 68"}, +{"message": "Log 69"}, +{"message": "Log 70"}, +{"message": "Log 71"}, +{"message": "Log 72"}, +{"message": "Log 73"}, +{"message": "Log 74"}, +{"message": "Log 75"}, +{"message": "Log 76"}, +{"message": "Log 77"}, +{"message": "Log 78"}, +{"message": "Log 79"}, +{"message": "Log 80"}, +{"message": "Log 81"}, +{"message": "Log 82"}, +{"message": "Log 83"}, +{"message": "Log 84"}, +{"message": "Log 85"}, +{"message": "Log 86"}, +{"message": "Log 87"}, +{"message": "Log 88"}, +{"message": "Log 89"}, +{"message": "Log 90"}, +{"message": "Log 91"}, +{"message": "Log 92"}, +{"message": "Log 93"}, +{"message": "Log 94"}, +{"message": "Log 95"}, +{"message": "Log 96"}, +{"message": "Log 97"}, +{"message": "Log 98"}, +{"message": "Log 99"}, +{"message": "Log 100"}, +{"message": "Log 101"}, +{"message": "Log 102"}, +{"message": "Log 103"}, +{"message": "Log 104"}, +{"message": "Log 105"}, +{"message": "Log 106"}, +{"message": "Log 107"}, +{"message": "Log 108"}, +{"message": "Log 109"}, +{"message": "Log 110"}, +{"message": "Log 111"}, +{"message": "Log 112"}, +{"message": "Log 113"}, +{"message": "Log 114"}, +{"message": "Log 115"}, +{"message": "Log 116"}, +{"message": "Log 117"}, +{"message": "Log 118"}, +{"message": "Log 119"}, +{"message": "Log 120"}, +{"message": "Log 121"}, +{"message": "Log 122"}, +{"message": "Log 123"}, +{"message": "Log 124"}, +{"message": "Log 125"}, +{"message": "Log 126"}, +{"message": "Log 127"}, +{"message": "Log 128"}, +{"message": "Log 129"}, +{"message": "Log 130"}, +{"message": "Log 131"}, +{"message": "Log 132"}, +{"message": "Log 133"}, +{"message": "Log 134"}, +{"message": "Log 135"}, +{"message": "Log 136"}, +{"message": "Log 137"}, +{"message": "Log 138"}, +{"message": "Log 139"}, +{"message": "Log 140"}, +{"message": "Log 141"}, +{"message": "Log 142"}, +{"message": "Log 143"}, +{"message": "Log 144"}, +{"message": "Log 145"}, +{"message": "Log 146"}, +{"message": "Log 147"}, +{"message": "Log 148"}, +{"message": "Log 149"}, +{"message": "Log 150"}, +{"message": "Log 151"}, +{"message": "Log 152"}, +{"message": "Log 153"}, +{"message": "Log 154"}, +{"message": "Log 155"}, +{"message": "Log 156"}, +{"message": "Log 157"}, +{"message": "Log 158"}, +{"message": "Log 159"}, +{"message": "Log 160"}, +{"message": "Log 161"}, +{"message": "Log 162"}, +{"message": "Log 163"}, +{"message": "Log 164"}, +{"message": "Log 165"}, +{"message": "Log 166"}, +{"message": "Log 167"}, +{"message": "Log 168"}, +{"message": "Log 169"}, +{"message": "Log 170"}, +{"message": "Log 171"}, +{"message": "Log 172"}, +{"message": "Log 173"}, +{"message": "Log 174"}, +{"message": "Log 175"}, +{"message": "Log 176"}, +{"message": "Log 177"}, +{"message": "Log 178"}, +{"message": "Log 179"}, +{"message": "Log 180"}, +{"message": "Log 181"}, +{"message": "Log 182"}, +{"message": "Log 183"}, +{"message": "Log 184"}, +{"message": "Log 185"}, +{"message": "Log 186"}, +{"message": "Log 187"}, +{"message": "Log 188"}, +{"message": "Log 189"}, +{"message": "Log 190"}, +{"message": "Log 191"}, +{"message": "Log 192"}, +{"message": "Log 193"}, +{"message": "Log 194"}, +{"message": "Log 195"}, +{"message": "Log 196"}, +{"message": "Log 197"}, +{"message": "Log 198"}, +{"message": "Log 199"}, +{"message": "Log 200"}, +{"message": "Log 201"}, +{"message": "Log 202"}, +{"message": "Log 203"}, +{"message": "Log 204"}, +{"message": "Log 205"}, +{"message": "Log 206"}, +{"message": "Log 207"}, +{"message": "Log 208"}, +{"message": "Log 209"}, +{"message": "Log 210"}, +{"message": "Log 211"}, +{"message": "Log 212"}, +{"message": "Log 213"}, +{"message": "Log 214"}, +{"message": "Log 215"}, +{"message": "Log 216"}, +{"message": "Log 217"}, +{"message": "Log 218"}, +{"message": "Log 219"}, +{"message": "Log 220"} +] +[[0,0.0,0.0],220] +select Logs --filter '_id <= 2 && message @ "LOG"' +[ + [ + 0, + 0.0, + 0.0 + ], + [ + [ + [ + 2 + ], + [ + [ + "_id", + "UInt32" + ], + [ + "message", + "ShortText" + ] + ], + [ + 1, + "Log 1" + ], + [ + 2, + "Log 2" + ] + ] + ] +] Added: test/command/suite/select/index/match/string/too_many.test (+233 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/select/index/match/string/too_many.test 2014-11-11 18:21:11 +0900 (494be4d) @@ -0,0 +1,233 @@ +table_create Logs TABLE_NO_KEY +column_create Logs message COLUMN_SCALAR ShortText + +table_create Terms TABLE_PAT_KEY ShortText \ + --default_tokenizer TokenBigram \ + --normalizer NormalizerAuto +column_create Terms logs_message COLUMN_INDEX|WITH_SECTION Logs message + +load --table Logs +[ +{"message": "Log 1"}, +{"message": "Log 2"}, +{"message": "Log 3"}, +{"message": "Log 4"}, +{"message": "Log 5"}, +{"message": "Log 6"}, +{"message": "Log 7"}, +{"message": "Log 8"}, +{"message": "Log 9"}, +{"message": "Log 10"}, +{"message": "Log 11"}, +{"message": "Log 12"}, +{"message": "Log 13"}, +{"message": "Log 14"}, +{"message": "Log 15"}, +{"message": "Log 16"}, +{"message": "Log 17"}, +{"message": "Log 18"}, +{"message": "Log 19"}, +{"message": "Log 20"}, +{"message": "Log 21"}, +{"message": "Log 22"}, +{"message": "Log 23"}, +{"message": "Log 24"}, +{"message": "Log 25"}, +{"message": "Log 26"}, +{"message": "Log 27"}, +{"message": "Log 28"}, +{"message": "Log 29"}, +{"message": "Log 30"}, +{"message": "Log 31"}, +{"message": "Log 32"}, +{"message": "Log 33"}, +{"message": "Log 34"}, +{"message": "Log 35"}, +{"message": "Log 36"}, +{"message": "Log 37"}, +{"message": "Log 38"}, +{"message": "Log 39"}, +{"message": "Log 40"}, +{"message": "Log 41"}, +{"message": "Log 42"}, +{"message": "Log 43"}, +{"message": "Log 44"}, +{"message": "Log 45"}, +{"message": "Log 46"}, +{"message": "Log 47"}, +{"message": "Log 48"}, +{"message": "Log 49"}, +{"message": "Log 50"}, +{"message": "Log 51"}, +{"message": "Log 52"}, +{"message": "Log 53"}, +{"message": "Log 54"}, +{"message": "Log 55"}, +{"message": "Log 56"}, +{"message": "Log 57"}, +{"message": "Log 58"}, +{"message": "Log 59"}, +{"message": "Log 60"}, +{"message": "Log 61"}, +{"message": "Log 62"}, +{"message": "Log 63"}, +{"message": "Log 64"}, +{"message": "Log 65"}, +{"message": "Log 66"}, +{"message": "Log 67"}, +{"message": "Log 68"}, +{"message": "Log 69"}, +{"message": "Log 70"}, +{"message": "Log 71"}, +{"message": "Log 72"}, +{"message": "Log 73"}, +{"message": "Log 74"}, +{"message": "Log 75"}, +{"message": "Log 76"}, +{"message": "Log 77"}, +{"message": "Log 78"}, +{"message": "Log 79"}, +{"message": "Log 80"}, +{"message": "Log 81"}, +{"message": "Log 82"}, +{"message": "Log 83"}, +{"message": "Log 84"}, +{"message": "Log 85"}, +{"message": "Log 86"}, +{"message": "Log 87"}, +{"message": "Log 88"}, +{"message": "Log 89"}, +{"message": "Log 90"}, +{"message": "Log 91"}, +{"message": "Log 92"}, +{"message": "Log 93"}, +{"message": "Log 94"}, +{"message": "Log 95"}, +{"message": "Log 96"}, +{"message": "Log 97"}, +{"message": "Log 98"}, +{"message": "Log 99"}, +{"message": "Log 100"}, +{"message": "Log 101"}, +{"message": "Log 102"}, +{"message": "Log 103"}, +{"message": "Log 104"}, +{"message": "Log 105"}, +{"message": "Log 106"}, +{"message": "Log 107"}, +{"message": "Log 108"}, +{"message": "Log 109"}, +{"message": "Log 110"}, +{"message": "Log 111"}, +{"message": "Log 112"}, +{"message": "Log 113"}, +{"message": "Log 114"}, +{"message": "Log 115"}, +{"message": "Log 116"}, +{"message": "Log 117"}, +{"message": "Log 118"}, +{"message": "Log 119"}, +{"message": "Log 120"}, +{"message": "Log 121"}, +{"message": "Log 122"}, +{"message": "Log 123"}, +{"message": "Log 124"}, +{"message": "Log 125"}, +{"message": "Log 126"}, +{"message": "Log 127"}, +{"message": "Log 128"}, +{"message": "Log 129"}, +{"message": "Log 130"}, +{"message": "Log 131"}, +{"message": "Log 132"}, +{"message": "Log 133"}, +{"message": "Log 134"}, +{"message": "Log 135"}, +{"message": "Log 136"}, +{"message": "Log 137"}, +{"message": "Log 138"}, +{"message": "Log 139"}, +{"message": "Log 140"}, +{"message": "Log 141"}, +{"message": "Log 142"}, +{"message": "Log 143"}, +{"message": "Log 144"}, +{"message": "Log 145"}, +{"message": "Log 146"}, +{"message": "Log 147"}, +{"message": "Log 148"}, +{"message": "Log 149"}, +{"message": "Log 150"}, +{"message": "Log 151"}, +{"message": "Log 152"}, +{"message": "Log 153"}, +{"message": "Log 154"}, +{"message": "Log 155"}, +{"message": "Log 156"}, +{"message": "Log 157"}, +{"message": "Log 158"}, +{"message": "Log 159"}, +{"message": "Log 160"}, +{"message": "Log 161"}, +{"message": "Log 162"}, +{"message": "Log 163"}, +{"message": "Log 164"}, +{"message": "Log 165"}, +{"message": "Log 166"}, +{"message": "Log 167"}, +{"message": "Log 168"}, +{"message": "Log 169"}, +{"message": "Log 170"}, +{"message": "Log 171"}, +{"message": "Log 172"}, +{"message": "Log 173"}, +{"message": "Log 174"}, +{"message": "Log 175"}, +{"message": "Log 176"}, +{"message": "Log 177"}, +{"message": "Log 178"}, +{"message": "Log 179"}, +{"message": "Log 180"}, +{"message": "Log 181"}, +{"message": "Log 182"}, +{"message": "Log 183"}, +{"message": "Log 184"}, +{"message": "Log 185"}, +{"message": "Log 186"}, +{"message": "Log 187"}, +{"message": "Log 188"}, +{"message": "Log 189"}, +{"message": "Log 190"}, +{"message": "Log 191"}, +{"message": "Log 192"}, +{"message": "Log 193"}, +{"message": "Log 194"}, +{"message": "Log 195"}, +{"message": "Log 196"}, +{"message": "Log 197"}, +{"message": "Log 198"}, +{"message": "Log 199"}, +{"message": "Log 200"}, +{"message": "Log 201"}, +{"message": "Log 202"}, +{"message": "Log 203"}, +{"message": "Log 204"}, +{"message": "Log 205"}, +{"message": "Log 206"}, +{"message": "Log 207"}, +{"message": "Log 208"}, +{"message": "Log 209"}, +{"message": "Log 210"}, +{"message": "Log 211"}, +{"message": "Log 212"}, +{"message": "Log 213"}, +{"message": "Log 214"}, +{"message": "Log 215"}, +{"message": "Log 216"}, +{"message": "Log 217"}, +{"message": "Log 218"}, +{"message": "Log 219"}, +{"message": "Log 220"} +] + +select Logs --filter '_id <= 2 && message @ "LOG"' -------------- next part -------------- HTML����������������������������...Download