Advertisement
Guest User

Ignite CacheQueryTypeMetadataExample

a guest
Apr 15th, 2015
442
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 17.18 KB | None | 0 0
  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17.  
  18. package org.apache.ignite.examples.datagrid;
  19.  
  20. import org.apache.ignite.*;
  21. import org.apache.ignite.cache.*;
  22. import org.apache.ignite.cache.affinity.*;
  23. import org.apache.ignite.cache.query.*;
  24. import org.apache.ignite.configuration.*;
  25. import org.apache.ignite.examples.*;
  26. import org.apache.ignite.lang.*;
  27.  
  28. import javax.cache.*;
  29. import java.io.*;
  30. import java.util.*;
  31.  
  32. /**
  33.  * Cache queries example. This example demonstrates SQL, TEXT, and FULL SCAN
  34.  * queries over cache.
  35.  * <p>
  36.  * Example also demonstrates usage of fields queries that return only required
  37.  * fields instead of whole key-value pairs. When fields queries are distributed
  38.  * across several nodes, they may not work as expected. Keep in mind following
  39.  * limitations (not applied if data is queried from one node only):
  40.  * <ul>
  41.  *     <li>
  42.  *         Joins will work correctly only if joined objects are stored in
  43.  *         collocated mode. Refer to {@link AffinityKey} javadoc for more details.
  44.  *     </li>
  45.  *     <li>
  46.  *         Note that if you created query on to replicated cache, all data will
  47.  *         be queried only on one node, not depending on what caches participate in
  48.  *         the query (some data from partitioned cache can be lost). And visa versa,
  49.  *         if you created it on partitioned cache, data from replicated caches
  50.  *         will be duplicated.
  51.  *     </li>
  52.  * </ul>
  53.  * <p>
  54.  * Remote nodes should be started using {@link ExampleNodeStartup} which will
  55.  * start node with {@code examples/config/example-ignite.xml} configuration.
  56.  */
  57. public class CacheQueryTypeMetadataExample {
  58.     /** Organizations cache name. */
  59.     private static final String ORG_CACHE = CacheQueryTypeMetadataExample.class.getSimpleName() + "Organizations";
  60.  
  61.     /** Persons cache name. */
  62.     private static final String PERSON_CACHE = CacheQueryTypeMetadataExample.class.getSimpleName() + "Persons";
  63.  
  64.     /**
  65.      * @return Organisation type metadata.
  66.      */
  67.     private static Collection<CacheTypeMetadata> orgTypeMetadata() {
  68.         Collection<CacheTypeMetadata> types = new ArrayList<>();
  69.  
  70.         CacheTypeMetadata type = new CacheTypeMetadata();
  71.         type.setValueType(Organization.class.getName());
  72.  
  73.         Map<String, Class<?>> qryFlds = type.getQueryFields();
  74.         qryFlds.put("id", UUID.class);
  75.         qryFlds.put("name", String.class);
  76.  
  77.         Map<String, Class<?>> ascFlds = type.getAscendingFields();
  78.         ascFlds.put("id", UUID.class);
  79.         ascFlds.put("name", String.class);
  80.  
  81.         types.add(type);
  82.  
  83.         return types;
  84.     }
  85.  
  86.     /**
  87.      * @return Person type metadata.
  88.      */
  89.     private static Collection<CacheTypeMetadata> personTypeMetadata() {
  90.     Collection<CacheTypeMetadata> types = new ArrayList<>();
  91.  
  92.     CacheTypeMetadata type = new CacheTypeMetadata();
  93.     type.setValueType(Person.class.getName());
  94.  
  95.     Map<String, Class<?>> qryFlds = type.getQueryFields();
  96.     qryFlds.put("id", UUID.class);
  97.     qryFlds.put("orgId", UUID.class);
  98.     qryFlds.put("firstName", String.class);
  99.     qryFlds.put("lastName", String.class);
  100.     qryFlds.put("resume", String.class);
  101.     qryFlds.put("salary", double.class);
  102.  
  103.     Map<String, Class<?>> ascFlds = type.getAscendingFields();
  104.     ascFlds.put("id", UUID.class);
  105.     ascFlds.put("orgId", UUID.class);
  106.     ascFlds.put("salary", double.class);
  107.  
  108.     Collection<String> txtFlds = type.getTextFields();
  109.     txtFlds.add("resume");
  110.  
  111.     types.add(type);
  112.  
  113.         return types;
  114.     }
  115.  
  116.     /**
  117.      * Executes example.
  118.      *
  119.      * @param args Command line arguments, none required.
  120.      * @throws Exception If example execution failed.
  121.      */
  122.     public static void main(String[] args) throws Exception {
  123.         try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
  124.             System.out.println();
  125.             System.out.println(">>> Cache query example started.");
  126.  
  127.             // Configure cache for Organizations.
  128.             CacheConfiguration<UUID, Organization> orgCacheCfg = new CacheConfiguration<>(ORG_CACHE);
  129.             orgCacheCfg.setCacheMode(CacheMode.PARTITIONED);
  130.             orgCacheCfg.setTypeMetadata(orgTypeMetadata());
  131.  
  132.             // Configure cache for Persons.
  133.             CacheConfiguration<AffinityKey<UUID>, Person> personCacheCfg = new CacheConfiguration<>(PERSON_CACHE);
  134.             personCacheCfg.setCacheMode(CacheMode.PARTITIONED);
  135.             personCacheCfg.setTypeMetadata(personTypeMetadata());
  136.  
  137.             try (
  138.                 IgniteCache<UUID, Organization> orgCache = ignite.createCache(orgCacheCfg);
  139.                 IgniteCache<AffinityKey<UUID>, Person> personCache = ignite.createCache(personCacheCfg)
  140.             ) {
  141.                 // Populate cache.
  142.                 initialize();
  143.  
  144.                 // Example for SCAN-based query based on a predicate.
  145.                 scanQuery();
  146.  
  147.                 // Example for SQL-based querying employees based on salary ranges.
  148.                 sqlQuery();
  149.  
  150.                 // Example for SQL-based querying employees for a given organization (includes SQL join).
  151.                 sqlQueryWithJoin();
  152.  
  153.                 // Example for TEXT-based querying for a given string in peoples resumes.
  154.                 textQuery();
  155.  
  156.                 // Example for SQL-based querying to calculate average salary among all employees within a company.
  157.                 sqlQueryWithAggregation();
  158.  
  159.                 // Example for SQL-based fields queries that return only required
  160.                 // fields instead of whole key-value pairs.
  161.                 sqlFieldsQuery();
  162.  
  163.                 // Example for SQL-based fields queries that uses joins.
  164.                 sqlFieldsQueryWithJoin();
  165.             }
  166.  
  167.             print("Cache query type metadata example finished.");
  168.         }
  169.     }
  170.  
  171.     /**
  172.      * Example for scan query based on a predicate.
  173.      */
  174.     private static void scanQuery() {
  175.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  176.  
  177.         ScanQuery<AffinityKey<UUID>, Person> scan = new ScanQuery<>(
  178.             new IgniteBiPredicate<AffinityKey<UUID>, Person>() {
  179.                 @Override public boolean apply(AffinityKey<UUID> key, Person person) {
  180.                     return person.salary <= 1000;
  181.                 }
  182.             }
  183.         );
  184.  
  185.         // Execute queries for salary ranges.
  186.         print("People with salaries between 0 and 1000 (queried with SCAN query): ", cache.query(scan).getAll());
  187.     }
  188.  
  189.     /**
  190.      * Example for SQL queries based on salary ranges.
  191.      */
  192.     private static void sqlQuery() {
  193.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  194.  
  195.         // SQL clause which selects salaries based on range.
  196.         String sql = "salary > ? and salary <= ?";
  197.  
  198.         // Execute queries for salary ranges.
  199.         print("People with salaries between 0 and 1000 (queried with SQL query): ",
  200.             cache.query(new SqlQuery<AffinityKey<UUID>, Person>(Person.class, sql).
  201.                 setArgs(0, 1000)).getAll());
  202.  
  203.         print("People with salaries between 1000 and 2000 (queried with SQL query): ",
  204.             cache.query(new SqlQuery<AffinityKey<UUID>, Person>(Person.class, sql).
  205.                 setArgs(1000, 2000)).getAll());
  206.     }
  207.  
  208.     /**
  209.      * Example for SQL queries based on all employees working for a specific organization.
  210.      */
  211.     private static void sqlQueryWithJoin() {
  212.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  213.  
  214.         // SQL clause query which joins on 2 types to select people for a specific organization.
  215.         String joinSql =
  216.             "from Person, \"" + ORG_CACHE + "\".Organization as org " +
  217.             "where Person.orgId = org.id " +
  218.             "and lower(org.name) = lower(?)";
  219.  
  220.         // Execute queries for find employees for different organizations.
  221.         print("Following people are 'ApacheIgnite' employees: ",
  222.             cache.query(new SqlQuery<AffinityKey<UUID>, Person>(Person.class, joinSql).
  223.                 setArgs("ApacheIgnite")).getAll());
  224.  
  225.         print("Following people are 'Other' employees: ",
  226.             cache.query(new SqlQuery<AffinityKey<UUID>, Person>(Person.class, joinSql).
  227.                 setArgs("Other")).getAll());
  228.     }
  229.  
  230.     /**
  231.      * Example for TEXT queries using LUCENE-based indexing of people's resumes.
  232.      */
  233.     private static void textQuery() {
  234.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  235.  
  236.         //  Query for all people with "Master Degree" in their resumes.
  237.         QueryCursor<Cache.Entry<AffinityKey<UUID>, Person>> masters =
  238.             cache.query(new TextQuery<AffinityKey<UUID>, Person>(Person.class, "Master"));
  239.  
  240.         // Query for all people with "Bachelor Degree" in their resumes.
  241.         QueryCursor<Cache.Entry<AffinityKey<UUID>, Person>> bachelors =
  242.             cache.query(new TextQuery<AffinityKey<UUID>, Person>(Person.class, "Bachelor"));
  243.  
  244.         print("Following people have 'Master Degree' in their resumes: ", masters.getAll());
  245.         print("Following people have 'Bachelor Degree' in their resumes: ", bachelors.getAll());
  246.     }
  247.  
  248.     /**
  249.      * Example for SQL queries to calculate average salary for a specific organization.
  250.      */
  251.     private static void sqlQueryWithAggregation() {
  252.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  253.  
  254.         // Calculate average of salary of all persons in ApacheIgnite.
  255.         // Note that we also join on Organization cache as well.
  256.         String sql =
  257.             "select avg(salary) " +
  258.             "from Person, \"" + ORG_CACHE + "\".Organization as org " +
  259.             "where Person.orgId = org.id " +
  260.             "and lower(org.name) = lower(?)";
  261.  
  262.         QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery(sql).setArgs("ApacheIgnite"));
  263.  
  264.         // Calculate average salary for a specific organization.
  265.         print("Average salary for 'ApacheIgnite' employees: ", cursor.getAll());
  266.     }
  267.  
  268.     /**
  269.      * Example for SQL-based fields queries that return only required
  270.      * fields instead of whole key-value pairs.
  271.      */
  272.     private static void sqlFieldsQuery() {
  273.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  274.  
  275.         // Execute query to get names of all employees.
  276.         QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery(
  277.             "select concat(firstName, ' ', lastName) from Person"));
  278.  
  279.         // In this particular case each row will have one element with full name of an employees.
  280.         List<List<?>> res = cursor.getAll();
  281.  
  282.         // Print names.
  283.         print("Names of all employees:", res);
  284.     }
  285.  
  286.     /**
  287.      * Example for SQL-based fields queries that return only required
  288.      * fields instead of whole key-value pairs.
  289.      */
  290.     private static void sqlFieldsQueryWithJoin() {
  291.         IgniteCache<AffinityKey<UUID>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);
  292.  
  293.         // Execute query to get names of all employees.
  294.         String sql =
  295.             "select concat(firstName, ' ', lastName), org.name " +
  296.             "from Person, \"" + ORG_CACHE + "\".Organization as org " +
  297.             "where Person.orgId = org.id";
  298.  
  299.         QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery(sql));
  300.  
  301.         // In this particular case each row will have one element with full name of an employees.
  302.         List<List<?>> res = cursor.getAll();
  303.  
  304.         // Print persons' names and organizations' names.
  305.         print("Names of all employees and organizations they belong to:", res);
  306.     }
  307.  
  308.     /**
  309.      * Populate cache with test data.
  310.      */
  311.     private static void initialize() {
  312.         IgniteCache<UUID, Organization> orgCache = Ignition.ignite().cache(ORG_CACHE);
  313.  
  314.         // Organizations.
  315.         Organization org1 = new Organization("ApacheIgnite");
  316.         Organization org2 = new Organization("Other");
  317.  
  318.         orgCache.put(org1.id, org1);
  319.         orgCache.put(org2.id, org2);
  320.  
  321.         IgniteCache<AffinityKey<UUID>, Person> personCache = Ignition.ignite().cache(PERSON_CACHE);
  322.  
  323.         // People.
  324.         Person p1 = new Person(org1, "John", "Doe", 2000, "John Doe has Master Degree.");
  325.         Person p2 = new Person(org1, "Jane", "Doe", 1000, "Jane Doe has Bachelor Degree.");
  326.         Person p3 = new Person(org2, "John", "Smith", 1000, "John Smith has Bachelor Degree.");
  327.         Person p4 = new Person(org2, "Jane", "Smith", 2000, "Jane Smith has Master Degree.");
  328.  
  329.         // Note that in this example we use custom affinity key for Person objects
  330.         // to ensure that all persons are collocated with their organizations.
  331.         personCache.put(p1.key(), p1);
  332.         personCache.put(p2.key(), p2);
  333.         personCache.put(p3.key(), p3);
  334.         personCache.put(p4.key(), p4);
  335.     }
  336.  
  337.     /**
  338.      * Prints message and query results.
  339.      *
  340.      * @param msg Message to print before all objects are printed.
  341.      * @param col Query results.
  342.      */
  343.     private static void print(String msg, Iterable<?> col) {
  344.         print(msg);
  345.         print(col);
  346.     }
  347.  
  348.     /**
  349.      * Prints message.
  350.      *
  351.      * @param msg Message to print before all objects are printed.
  352.      */
  353.     private static void print(String msg) {
  354.         System.out.println();
  355.         System.out.println(">>> " + msg);
  356.     }
  357.  
  358.     /**
  359.      * Prints query results.
  360.      *
  361.      * @param col Query results.
  362.      */
  363.     private static void print(Iterable<?> col) {
  364.         for (Object next : col)
  365.             System.out.println(">>>     " + next);
  366.     }
  367.  
  368.     /**
  369.      * Person class.
  370.      */
  371.     private static class Person implements Serializable {
  372.         /** Person ID (indexed). */
  373.         private UUID id;
  374.  
  375.         /** Organization ID (indexed). */
  376.         private UUID orgId;
  377.  
  378.         /** First name (not-indexed). */
  379.         private String firstName;
  380.  
  381.         /** Last name (not indexed). */
  382.         private String lastName;
  383.  
  384.         /** Resume text (create LUCENE-based TEXT index for this field). */
  385.         private String resume;
  386.  
  387.         /** Salary (indexed). */
  388.         private double salary;
  389.  
  390.         /** Custom cache key to guarantee that person is always collocated with its organization. */
  391.         private transient AffinityKey<UUID> key;
  392.  
  393.         /**
  394.          * Constructs person record.
  395.          *
  396.          * @param org Organization.
  397.          * @param firstName First name.
  398.          * @param lastName Last name.
  399.          * @param salary Salary.
  400.          * @param resume Resume text.
  401.          */
  402.         Person(Organization org, String firstName, String lastName, double salary, String resume) {
  403.             // Generate unique ID for this person.
  404.             id = UUID.randomUUID();
  405.  
  406.             orgId = org.id;
  407.  
  408.             this.firstName = firstName;
  409.             this.lastName = lastName;
  410.             this.resume = resume;
  411.             this.salary = salary;
  412.         }
  413.  
  414.         /**
  415.          * Gets cache affinity key. Since in some examples person needs to be collocated with organization, we create
  416.          * custom affinity key to guarantee this collocation.
  417.          *
  418.          * @return Custom affinity key to guarantee that person is always collocated with organization.
  419.          */
  420.         public AffinityKey<UUID> key() {
  421.             if (key == null)
  422.                 key = new AffinityKey<>(id, orgId);
  423.  
  424.             return key;
  425.         }
  426.  
  427.         /** {@inheritDoc} */
  428.         @Override public String toString() {
  429.             return "Person [firstName=" + firstName +
  430.                 ", lastName=" + lastName +
  431.                 ", id=" + id +
  432.                 ", orgId=" + orgId +
  433.                 ", resume=" + resume +
  434.                 ", salary=" + salary + ']';
  435.         }
  436.     }
  437.  
  438.     /**
  439.      * Organization class.
  440.      */
  441.     private static class Organization implements Serializable {
  442.         /** Organization ID (indexed). */
  443.         private UUID id;
  444.  
  445.         /** Organization name (indexed). */
  446.         private String name;
  447.  
  448.         /**
  449.          * Create organization.
  450.          *
  451.          * @param name Organization name.
  452.          */
  453.         Organization(String name) {
  454.             id = UUID.randomUUID();
  455.  
  456.             this.name = name;
  457.         }
  458.  
  459.         /** {@inheritDoc} */
  460.         @Override public String toString() {
  461.             return "Organization [id=" + id + ", name=" + name + ']';
  462.         }
  463.     }
  464. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement