/* * Copyright (c) 2017 Strapdata (http://www.strapdata.com) * Contains some code from Elasticsearch (http://www.elastic.co) * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.elassandra; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.equalTo; import java.util.Map; import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.service.StorageService; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHits; import org.elasticsearch.test.ESSingleNodeTestCase; import org.junit.Test; /** * Elassandra composite key tests. * @author vroyer * */ public class CompositeTests extends ESSingleNodeTestCase { @Test public void testCompositeWithStaticColumnTest() throws Exception { XContentBuilder mapping = XContentFactory.jsonBuilder() .startObject() .startObject("properties") .startObject("id").field("type", "integer").field("cql_collection", "singleton").field("index", "no").field("cql_primary_key_order", 0).field("cql_partition_key", true).endObject() .startObject("surname").field("type", "string").field("cql_collection", "singleton").field("index", "analyzed").field("cql_primary_key_order", 1).field("cql_partition_key", true).endObject() .startObject("name").field("type", "string").field("cql_collection", "singleton").field("index", "analyzed").field("cql_primary_key_order", 2).endObject() .startObject("phonetic_name").field("type", "string").field("cql_collection", "singleton").field("index", "not_analyzed").field("cql_static_column", true).endObject() .startObject("nicks").field("type", "string").field("cql_collection", "list").field("index", "analyzed").endObject() .endObject() .endObject(); assertAcked(client().admin().indices().prepareCreate("test").setSettings(Settings.builder().put("index.token_ranges_bitset_cache",false).build()).addMapping("t2", mapping)); ensureGreen("test"); // INSERT INTO test.t2 (id, surname, name, phonetic_name, nicks) VALUES (22, 'Genesis', 'Abraham', 'ai-b-ram', ['the-A', 'ab']) process(ConsistencyLevel.ONE,"INSERT INTO test.t2 (id, surname, name, phonetic_name, nicks) VALUES (22, 'Genesis', 'Abraham', 'ai-b-ram', ['the-A', 'ab'])"); SearchResponse rsp = client().prepareSearch().setQuery("{ \"match_all\" : {} }").get(); assertThat(rsp.getHits().getTotalHits(), equalTo(2L)); } // mvn test -Pdev -pl com.strapdata.elasticsearch:elasticsearch -Dtests.seed=622A2B0618CE4676 -Dtests.class=org.elassandra.CompositeTests -Dtests.method="testCompositeTest" -Des.logger.level=ERROR -Dtests.assertion.disabled=false -Dtests.security.manager=false -Dtests.heap.size=1024m -Dtests.locale=ro-RO -Dtests.timezone=America/Toronto @Test public void testCompositeTest() throws Exception { createIndex("composite", Settings.builder().put("index.token_ranges_bitset_cache", false).build()); ensureGreen("composite"); process(ConsistencyLevel.ONE,"CREATE TABLE IF NOT EXISTS composite.t1 ( a text,b text,c bigint,f float,primary key ((a),b) )"); process(ConsistencyLevel.ONE,"CREATE TABLE IF NOT EXISTS composite.t2 ( a text,b text,c bigint,d bigint,primary key ((a),b,c) )"); process(ConsistencyLevel.ONE,"CREATE TABLE IF NOT EXISTS composite.t3 ( a text,b text,c bigint,d bigint,primary key ((a,b),c) )"); process(ConsistencyLevel.ONE,"CREATE TABLE IF NOT EXISTS composite.t11 ( a text,b text,c bigint,f float, s1 text static, primary key ((a),b) )"); process(ConsistencyLevel.ONE,"CREATE TABLE IF NOT EXISTS composite.t12 ( a text,b text,c bigint,d bigint,s1 text static, primary key ((a),b,c) )"); process(ConsistencyLevel.ONE,"CREATE TABLE IF NOT EXISTS composite.t13 ( a text,b text,c bigint,d bigint,s1 text static, primary key ((a,b),c) )"); assertAcked(client().admin().indices().preparePutMapping("composite").setType("t1").setSource("{ \"t1\" : { \"discover\" : \".*\" }}").get()); assertAcked(client().admin().indices().preparePutMapping("composite").setType("t2").setSource("{ \"t2\" : { \"discover\" : \".*\" }}").get()); assertAcked(client().admin().indices().preparePutMapping("composite").setType("t3").setSource("{ \"t3\" : { \"discover\" : \".*\" }}").get()); assertAcked(client().admin().indices().preparePutMapping("composite").setType("t11").setSource("{ \"t11\" : { \"discover\" : \".*\" }}").get()); assertAcked(client().admin().indices().preparePutMapping("composite").setType("t12").setSource("{ \"t12\" : { \"discover\" : \".*\" }}").get()); assertAcked(client().admin().indices().preparePutMapping("composite").setType("t13").setSource("{ \"t13\" : { \"discover\" : \".*\" }}").get()); process(ConsistencyLevel.ONE,"insert into composite.t1 (a,b,c,f) VALUES ('a','b1',1, 1.2)"); process(ConsistencyLevel.ONE,"insert into composite.t1 (a,b,c,f) VALUES ('b','b1',2, 5);"); process(ConsistencyLevel.ONE,"insert into composite.t2 (a,b,c,d) VALUES ('a','b2',2,1)"); process(ConsistencyLevel.ONE,"insert into composite.t2 (a,b,c,d) VALUES ('a','b2',3,1)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',2,3)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',3,3)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',4,4)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',5,5)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',6,6)"); process(ConsistencyLevel.ONE,"insert into composite.t11 (a,b,c,f,s1) VALUES ('a','b1',1, 1.2, 'a')"); process(ConsistencyLevel.ONE,"insert into composite.t11 (a,b,c,f,s1) VALUES ('b','b1',2, 5, 'b');"); process(ConsistencyLevel.ONE,"insert into composite.t12 (a,b,c,d,s1) VALUES ('a','b2',2,1, 'a1')"); process(ConsistencyLevel.ONE,"insert into composite.t12 (a,b,c,d,s1) VALUES ('a','b2',3,1, 'a2')"); process(ConsistencyLevel.ONE,"insert into composite.t13 (a,b,c,d,s1) VALUES ('a','b3',2,3, 'ab1')"); process(ConsistencyLevel.ONE,"insert into composite.t13 (a,b,c,d,s1) VALUES ('a','b3',3,3, 'ab2')"); process(ConsistencyLevel.ONE,"insert into composite.t13 (a,b,c,d,s1) VALUES ('a','b3',4,4, 'ab3')"); process(ConsistencyLevel.ONE,"insert into composite.t13 (a,b,c,d,s1) VALUES ('a','b3',5,5, 'ab4')"); process(ConsistencyLevel.ONE,"insert into composite.t13 (a,b,c,d,s1) VALUES ('a','b3',6,6, 'ab5')"); assertThat(client().prepareGet().setIndex("composite").setType("t1").setId("[\"a\",\"b1\"]").get().isExists(),equalTo(true)); assertThat(client().prepareGet().setIndex("composite").setType("t2").setId("[\"a\",\"b2\",2]").get().isExists(),equalTo(true)); assertThat(client().prepareGet().setIndex("composite").setType("t3").setId("[\"a\",\"b3\",2]").get().isExists(),equalTo(true)); assertThat(client().prepareGet().setIndex("composite").setType("t11").setId("[\"a\",\"b1\"]").get().isExists(),equalTo(true)); assertThat(client().prepareGet().setIndex("composite").setType("t12").setId("[\"a\",\"b2\",2]").get().isExists(),equalTo(true)); assertThat(client().prepareGet().setIndex("composite").setType("t13").setId("[\"a\",\"b3\",2]").get().isExists(),equalTo(true)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t1").setQuery(QueryBuilders.queryStringQuery("c:1")).get().getHits().getTotalHits(), equalTo(1L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t2").setQuery(QueryBuilders.queryStringQuery("d:1")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t3").setQuery(QueryBuilders.queryStringQuery("d:3")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t11").setQuery(QueryBuilders.queryStringQuery("c:1")).get().getHits().getTotalHits(), equalTo(1L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t12").setQuery(QueryBuilders.queryStringQuery("d:1")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t13").setQuery(QueryBuilders.queryStringQuery("d:3")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t11").setQuery(QueryBuilders.queryStringQuery("s1:b")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t12").setQuery(QueryBuilders.queryStringQuery("s1:a2")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareSearch().setIndices("composite").setTypes("t13").setQuery(QueryBuilders.queryStringQuery("s1:ab5")).get().getHits().getTotalHits(), equalTo(2L)); assertThat(client().prepareMultiGet().add("composite", "t1", "[\"a\",\"b1\"]", "[\"b\",\"b1\"]").get().getResponses()[0].getIndex(), equalTo("composite") ); assertThat(client().prepareMultiGet().add("composite", "t2", "[\"a\",\"b2\",2]", "[\"a\",\"b2\",3]").get().getResponses()[0].getIndex(), equalTo("composite") ); assertThat(client().prepareMultiGet().add("composite", "t3", "[\"a\",\"b3\",2]", "[\"a\",\"b3\",3]").get().getResponses()[0].getIndex(), equalTo("composite") ); assertThat(client().prepareMultiGet().add("composite", "t11", "[\"a\",\"b1\"]", "[\"b\",\"b1\"]").get().getResponses()[0].getIndex(), equalTo("composite") ); assertThat(client().prepareMultiGet().add("composite", "t12", "[\"a\",\"b2\",2]", "[\"a\",\"b2\",3]").get().getResponses()[0].getIndex(), equalTo("composite") ); assertThat(client().prepareMultiGet().add("composite", "t13", "[\"a\",\"b3\",2]", "[\"a\",\"b3\",3]").get().getResponses()[0].getIndex(), equalTo("composite") ); // delete with partition key process(ConsistencyLevel.ONE,"DELETE FROM composite.t1 WHERE a='a'"); assertThat(client().prepareSearch().setIndices("composite").setTypes("t1").setQuery(QueryBuilders.queryStringQuery("c:*")).get().getHits().getTotalHits(), equalTo(1L)); // delete with primary key process(ConsistencyLevel.ONE,"DELETE FROM composite.t2 WHERE a='a' AND b='b2' AND c=2"); assertThat(client().prepareSearch().setIndices("composite").setTypes("t2").setQuery(QueryBuilders.queryStringQuery("d:1")).get().getHits().getTotalHits(), equalTo(1L)); // delete a row process(ConsistencyLevel.ONE,"DELETE FROM composite.t3 WHERE a='a' AND b='b3' AND c = 4"); assertThat(client().prepareSearch().setIndices("composite").setTypes("t3").setQuery(QueryBuilders.queryStringQuery("a:a")).get().getHits().getTotalHits(), equalTo(4L)); // truncate content process(ConsistencyLevel.ONE,"TRUNCATE composite.t3"); assertThat(client().prepareSearch().setIndices("composite").setTypes("t3").setQuery(QueryBuilders.queryStringQuery("a:a")).get().getHits().getTotalHits(), equalTo(0L)); // test rebuild index assertAcked(client().admin().indices().prepareClose("composite").get()); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',2,3)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',3,3)"); process(ConsistencyLevel.ONE,"insert into composite.t3 (a,b,c,d) VALUES ('a','b3',4,4)"); assertAcked(client().admin().indices().prepareOpen("composite").get()); assertThat(client().prepareSearch().setIndices("composite").setTypes("t3").setQuery(QueryBuilders.queryStringQuery("a:a")).get().getHits().getTotalHits(), equalTo(0L)); StorageService.instance.forceKeyspaceFlush("composite", "t3"); StorageService.instance.rebuildSecondaryIndex("composite", "t3", "elastic_t3_d_idx"); assertThat(client().prepareSearch().setIndices("composite").setTypes("t3").setQuery(QueryBuilders.queryStringQuery("a:a")).get().getHits().getTotalHits(), equalTo(3L)); // delete index assertAcked(client().admin().indices().prepareDelete("composite").get()); } /* curl -XPUT "http://localhost:9200/test" -d '{ "mappings" : { "timeseries" : { "properties" : { "t" : { "type" : "date", "format" : "strict_date_optional_time||epoch_millis", "cql_primary_key_order" : 1, "cql_collection" : "singleton" }, "meta" : { "type" : "nested", "cql_struct" : "map", "cql_static_column" : true, "cql_collection" : "singleton", "include_in_parent" : true, "properties" : { "region" : { "type" : "string" } } }, "v" : { "type" : "double", "cql_collection" : "singleton" }, "m" : { "type" : "string", "cql_partition_key" : true, "cql_primary_key_order" : 0, "cql_collection" : "singleton" } } } } }' INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:30', 10); INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:31', 20); INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:32', 15); INSERT INTO test.timeseries (m, meta) VALUES ('server1-cpu', { 'region':'west' } ); curl -XGET "http://$NODE:9200/test/timeseries/_search?pretty=true&q=v:10&fields=m,t,v,meta.region" curl -XGET "http://$NODE:9200/test/timeseries/_search?pretty=true&q=meta.region:west&fields=m,t,v,meta.region" */ @Test public void testTimeserieWithStaticTest() throws Exception { XContentBuilder mapping = XContentFactory.jsonBuilder() .startObject() .startObject("properties") .startObject("m").field("type", "string").field("cql_collection", "singleton").field("index", "not_analyzed").field("cql_primary_key_order", 0).field("cql_partition_key", true).endObject() .startObject("t").field("type", "date").field("cql_collection", "singleton").field("cql_primary_key_order", 1).endObject() .startObject("v").field("type", "double").field("cql_collection", "singleton").endObject() .startObject("meta").field("type", "nested").field("cql_collection", "singleton").field("cql_struct", "map").field("cql_static_column", true).field("include_in_parent", true) .startObject("properties") .startObject("region").field("type", "string").field("index", "analyzed").endObject() .endObject() .endObject() .endObject() .endObject(); assertAcked(client().admin().indices().prepareCreate("test").addMapping("timeseries", mapping)); ensureGreen("test"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:30', 10);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:31', 20);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:32', 15);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, meta) VALUES ('server1-cpu', { 'region':'west' } );"); SearchResponse rsp = client().prepareSearch().setIndices("test").setTypes("timeseries") .setQuery(QueryBuilders.queryStringQuery("v:20")) .setFetchSource(new String[] { "m", "t", "v", "meta.region"}, null) .get(); SearchHits hits = rsp.getHits(); Map<String, Object> source = hits.hits()[0].getSource(); assertThat(hits.getTotalHits(), equalTo(1L)); assertThat(source.get("m"), equalTo("server1-cpu")); assertThat(((Map)source.get("meta")).get("region"), equalTo("west")); rsp = client().prepareSearch().setIndices("test").setTypes("timeseries") .setQuery(QueryBuilders.queryStringQuery("meta.region:west")) .setFetchSource(new String[] { "m", "meta.region"}, null) .get(); hits = rsp.getHits(); source = hits.hits()[0].getSource(); assertThat(hits.getTotalHits(), equalTo(1L)); assertThat(source.get("m"), equalTo("server1-cpu")); assertThat(((Map)source.get("meta")).get("region"), equalTo("west")); } @Test public void testTimeserieIndexStaticColumnsTest() throws Exception { XContentBuilder mapping = XContentFactory.jsonBuilder() .startObject() .startObject("properties") .startObject("m").field("type", "string").field("cql_collection", "singleton").field("index", "not_analyzed").field("cql_primary_key_order", 0).field("cql_partition_key", true).endObject() .startObject("t").field("type", "date").field("cql_collection", "singleton").field("cql_primary_key_order", 1).endObject() .startObject("v").field("type", "double").field("cql_collection", "singleton").endObject() .startObject("meta").field("type", "nested").field("cql_collection", "singleton").field("cql_struct", "map").field("cql_static_column", true).field("include_in_parent", true) .startObject("properties") .startObject("region").field("type", "string").field("index", "analyzed").endObject() .endObject() .endObject() .endObject() .startObject("_meta") .field("index_static_columns",true) .endObject() .endObject(); assertAcked(client().admin().indices().prepareCreate("test").addMapping("timeseries", mapping)); ensureGreen("test"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, meta) VALUES ('server1-cpu', { 'region':'west' } );"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:30', 10);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:31', 20);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:32', 15);"); SearchResponse rsp = client().prepareSearch().setIndices("test").setTypes("timeseries") .setQuery(QueryBuilders.queryStringQuery("meta.region:west")) .setFetchSource(new String[] { "m", "t", "v", "meta.region"}, null) .get(); SearchHits hits = rsp.getHits(); Map<String, Object> source = hits.hits()[0].getSource(); assertThat(hits.getTotalHits(), equalTo(4L)); assertThat(source.get("m"), equalTo("server1-cpu")); assertThat(((Map)source.get("meta")).get("region"), equalTo("west")); } @Test public void testTimeserieWithIndexedStaticOnlyTest() throws Exception { XContentBuilder mapping = XContentFactory.jsonBuilder() .startObject() .startObject("properties") .startObject("m").field("type", "string").field("cql_collection", "singleton").field("index", "not_analyzed").field("cql_primary_key_order", 0).field("cql_partition_key", true).endObject() .startObject("t").field("type", "date").field("cql_collection", "singleton").field("cql_primary_key_order", 1).endObject() .startObject("v").field("type", "double").field("cql_collection", "singleton").endObject() .startObject("meta").field("type", "nested").field("cql_collection", "singleton").field("cql_struct", "map").field("cql_static_column", true).field("include_in_parent", true) .startObject("properties") .startObject("region").field("type", "string").field("index", "analyzed").endObject() .endObject() .endObject() .endObject() .startObject("_meta") .field("index_static_only",true) .endObject() .endObject(); assertAcked(client().admin().indices().prepareCreate("test").addMapping("timeseries", mapping)); ensureGreen("test"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, meta) VALUES ('server1-cpu', { 'region':'west' } );"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:30', 10);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:31', 20);"); process(ConsistencyLevel.ONE,"INSERT INTO test.timeseries (m, t, v) VALUES ('server1-cpu', '2016-04-10 13:32', 15);"); SearchResponse rsp = client().prepareSearch().setIndices("test").setTypes("timeseries") .setQuery(QueryBuilders.queryStringQuery("meta.region:west")) .setFetchSource(new String[] { "m", "t", "v", "meta.region"}, null) .get(); SearchHits hits = rsp.getHits(); Map<String, Object> source = hits.hits()[0].getSource(); assertThat(hits.getTotalHits(), equalTo(1L)); assertThat(source.get("m"), equalTo("server1-cpu")); assertThat(((Map)source.get("meta")).get("region"), equalTo("west")); } }