如何使用密钥作为两个缓存/表的多列连接AffinityKey?

时间:2018-02-13 18:25:33

标签: ignite

我打算加入两个以多列为关键字的缓存。但我发现编写连接查询很困难。 这是完整的代码。请帮助使用两个缓存/表格编写连接查询

人物价值对象:

private static class Person implements Serializable {
        private PersonKey personKey;
        private OrgKey orgKey;
        @QuerySqlField
        private String firstName;
        @QuerySqlField
        private String lastName;
        @QueryTextField
        private String resume;
        /** Salary (indexed). */
        @QuerySqlField(index = true)
        private double salary;
        /**
         * Custom cache key to guarantee that person is always collocated with
         * its organization.
         */
        private transient AffinityKey<PersonKey> key;


        Person(Organization org, PersonKey key, String firstName, String lastName, double salary, String resume) {
            // Generate unique ID for this person.
            this.personKey = key;
            this.orgKey = org.key;
            this.firstName = firstName;
            this.lastName = lastName;
            this.resume = resume;
            this.salary = salary;
        }

人员关键对象:

private static class PersonKey implements Serializable {

        @QuerySqlField(index = true)
        private UUID id;
        @QuerySqlField(index = true)
        private String location;

        public PersonKey(UUID id, String location) {
            this.id = id;
            this.location = location;
        }
    }

组织价值对象:

private static class Organization implements Serializable {
        /** Organization ID (indexed). */
        private OrgKey key;
        /** Organization name (indexed). */
        @QuerySqlField(index = true)
        private String name;

        public Organization(OrgKey key, String name) {
            this.key = key;
            this.name = name;
        }

组织密钥类:

private static class OrgKey implements Serializable {

    @QuerySqlField(index = true)
    private int id;
    @QuerySqlField(index = true)
    private String location;
    private UUID orgId;

    public OrgKey(int id, String location, UUID orgId) {
        this.id = id;
        this.location = location;
        this.orgId = orgId;
    }
}

加入查询:

IgniteCache<AffinityKey<PersonKey>, Person> cache = Ignition.ignite().cache(PERSON_CACHE);

        String sql = "select * " + "from Persons, Organizations as org " + "where Persons.id = org.orgId";

        QueryCursor<List<?>> cursor = cache.query(new SqlFieldsQuery(sql));

点击缓存创建:

/** Organizations cache name. */
    private static final String ORG_CACHE = "Organizations";
    /** Persons cache name. */
    private static final String PERSON_CACHE = "Persons";

    CacheConfiguration<OrgKey, Organization> orgCacheCfg = new CacheConfiguration<>(ORG_CACHE);
                orgCacheCfg.setCacheMode(CacheMode.PARTITIONED); // Default.
                orgCacheCfg.setIndexedTypes(OrgKey.class, Organization.class);

                CacheConfiguration<AffinityKey<PersonKey>, Person> personCacheCfg = new CacheConfiguration<>(PERSON_CACHE);
                personCacheCfg.setCacheMode(CacheMode.PARTITIONED); // Default.
                personCacheCfg.setIndexedTypes(AffinityKey.class, Person.class);

2 个答案:

答案 0 :(得分:1)

请查看这个简单的示例,我通过键中的两个字段加入:

package sql;

import java.util.Arrays;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.jetbrains.annotations.NotNull;

public class DoubleJoin {
    public static final String DEFAULT_CACHE_NAME = "DEFAULT";

    public static void main(String[] args) throws InterruptedException {
        IgniteConfiguration ignCfg = new IgniteConfiguration();

        TcpDiscoverySpi spi = new TcpDiscoverySpi();
        TcpDiscoveryVmIpFinder finder = new TcpDiscoveryVmIpFinder();
        finder.setAddresses(Arrays.asList("127.0.0.1"));
        spi.setIpFinder(finder);

        ignCfg.setDiscoverySpi(spi);

        Ignite ignite = Ignition.start(ignCfg);

        CacheConfiguration cacheCfg = getCacheConfiguration();

        final IgniteCache cache = ignite.getOrCreateCache(cacheCfg);

        cache.put(new A(1, 2), new AVal(100));
        cache.put(new B(1, 2), new BVal(100));

        FieldsQueryCursor cursor = cache.query(new SqlFieldsQuery("SELECT * " +
            "FROM AVal " +
            "INNER JOIN BVal ON AVal.a1=BVal.b1 AND AVal.a2=BVal.b2;"));

        for (Object o : cursor) {
            System.out.println(o);
        }
    }

    static class A {
        @AffinityKeyMapped
        @QuerySqlField
        int a1;
        @QuerySqlField
        int a2;

        public A(int a1, int a2) {
            this.a1 = a1;
            this.a2 = a2;
        }
    }

    static class AVal {
        @QuerySqlField
        int aV;

        public AVal(int aV) {
            this.aV = aV;
        }
    }

    static class B {
        @AffinityKeyMapped
        @QuerySqlField
        int b1;
        @QuerySqlField
        int b2;

        public B(int b1, int b2) {
            this.b1 = b1;
            this.b2 = b2;
        }
    }

    static class BVal {
        @QuerySqlField
        int bV;

        public BVal(int bV) {
            this.bV = bV;
        }
    }

    @NotNull private static CacheConfiguration<Integer, Integer> getCacheConfiguration() {
        CacheConfiguration<Integer, Integer> cfg = new CacheConfiguration<>();

        cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
        cfg.setName(DEFAULT_CACHE_NAME);

        cfg.setIndexedTypes(A.class, AVal.class, B.class, BVal.class);

        return cfg;
    }
}

答案 1 :(得分:0)

我对CLASS A进行了一些小修改,如果我错了,请纠正我。我使用了关键字映射器,如下面的链接。 https://apacheignite.readme.io/docs/affinity-collocation

 package com.cache;

import java.util.Arrays;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.affinity.AffinityKeyMapped;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.annotations.QuerySqlField;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.jetbrains.annotations.NotNull;

public class DoubleJoin {
    public static final String DEFAULT_CACHE_NAME = "DEFAULT";

    public static void main(String[] args) throws InterruptedException {
        IgniteConfiguration ignCfg = new IgniteConfiguration();

        TcpDiscoverySpi spi = new TcpDiscoverySpi();
        TcpDiscoveryVmIpFinder finder = new TcpDiscoveryVmIpFinder();
        finder.setAddresses(Arrays.asList("127.0.0.1"));
        spi.setIpFinder(finder);

        ignCfg.setDiscoverySpi(spi);

        Ignite ignite = Ignition.start(ignCfg);

        CacheConfiguration cacheCfg = getCacheConfiguration();

        final IgniteCache cache = ignite.getOrCreateCache(cacheCfg);

        cache.put(new A(1, 2), new AVal(100, new A(1, 2)));
        cache.put(new A(2, 3), new AVal(200, new A(2, 3)));
        cache.put(new A(3, 4), new AVal(300, new A(3, 4)));
        cache.put(new B(1, 2), new BVal(200));

        FieldsQueryCursor cursor = cache.query(new SqlFieldsQuery("SELECT BVall.b1, BVall.b2, BVall.bV " + "FROM AVal "
                + "INNER JOIN (select *  from BVal where BVal.bV = ?) BVall ON AVal.a1=BVall.b1 AND AVal.a2=BVall.b2  ;").setArgs(200));

        for (Object o : cursor) {
            System.out.println(o);
        }
    }

    static class A {
        @QuerySqlField
        int a1;
        @QuerySqlField
        int a2;
        @AffinityKeyMapped
        int b1;
        @AffinityKeyMapped
        int b2;

        public A(int a1, int a2) {
            this.a1 = a1;
            this.a2 = a2;
            this.b1 = a1;
            this.b2 = a2;
        }
    }

    static class AVal {
        @QuerySqlField
        int aV;

        A a;

        public AVal(int aV,  A a) {
            this.aV = aV;
            this.a = a;
        }
    }

    static class B {
        @QuerySqlField
        int b1;
        @QuerySqlField
        int b2;

        public B(int b1, int b2) {
            this.b1 = b1;
            this.b2 = b2;
        }
    }

    static class BVal {
        @QuerySqlField
        int bV;

        public BVal(int bV) {
            this.bV = bV;
        }
    }

    @NotNull
    private static CacheConfiguration<Integer, Integer> getCacheConfiguration() {
        CacheConfiguration<Integer, Integer> cfg = new CacheConfiguration<>();

        cfg.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
        cfg.setName(DEFAULT_CACHE_NAME);

        cfg.setIndexedTypes(A.class, AVal.class, B.class, BVal.class);

        return cfg;
    }
}