3

我刚刚开始探索 PlayOrm 并尝试运行网络上可用的基本代码来插入和读取数据。当我插入数据时,一切似乎都工作正常,但在读取相同的数据时,它返回的行数不正确。例如。如果我插入 3 条记录,有时会得到 0 条记录,有时会返回所有记录。

按照我正在使用的代码:

用于插入/读取数据的类:

  @NoSqlEntity
  @NoSqlQueries({
    @NoSqlQuery(name="findByLastName", query="PARTITIONS t('lastName',:lastName) select *  FROM TABLE as t"),
    @NoSqlQuery(name="findByName", query="PARTITIONS e('name',:name) select *  FROM TABLE as e")
  })

  public class User {

    @NoSqlId
    private String id;

    @NoSqlPartitionByThisField
    private String name;

    @NoSqlIndexed
    private int age;

    @NoSqlPartitionByThisField
    @NoSqlIndexed
    private String lastName;

    public String getId() {
            return id;
    }

    public void setId(String id) {
            this.id = id;
    }

    public int getAge() {
            return age;
    }

    public void setAge(int age) {
            this.age = age;
    }

    public String getName() {
            return name;
    }

    public void setName(String name) {
            this.name = name;
    }

    public String getLastName() {
            return lastName;
    }

    public void setLastName(String lastName) {
            this.lastName = lastName;
    }
    /*
     * Queries:
     *      @NoSqlQuery(name="findByLastName", query="PARTITIONS t('lastName',:lastName) select *  FROM TABLE as t"),
     *      @NoSqlQuery(name="findByName", query="PARTITIONS e('name',:name) select *  FROM TABLE as e")
     */

    public static List<User> findByLastName(NoSqlEntityManager mgr, String lastName) {
            Query<User> query = mgr.createNamedQuery(User.class, "findByLastName");
            System.out.println("Using last name "+lastName);
            query.setParameter("lastName", lastName);
            return query.getResultList(0, 100);
    }

    public static List<User> findByName(NoSqlEntityManager mgr, String name) {
            Query<User> query = mgr.createNamedQuery(User.class, "findByName");
            System.out.println("Using name "+name);
            query.setParameter("name", name);
            return query.getResultList(0, 100);
    }

  }

使用此类的代码:

import java.awt.List;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import com.alvazan.orm.api.base.Bootstrap;
import com.alvazan.orm.api.base.DbTypeEnum;
import com.alvazan.orm.api.base.NoSqlEntityManager;
import com.alvazan.orm.api.base.NoSqlEntityManagerFactory;
import com.netflix.astyanax.retry.SleepingRetryPolicy;

public class Example {

private static NoSqlEntityManager mgr;
public static void main(String[] args) {
    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put(Bootstrap.AUTO_CREATE_KEY, "create");
    /*
     * Bootstrap.createAndAddBestCassandraConfiguration(properties, clusterName, keyspace, seeds);
     * NoSqlEntityManagerFactory factory = Bootstrap.create(DbTypeEnum.CASSANDRA, properties,null,null);
     */
    NoSqlEntityManagerFactory factory = Bootstrap.create(DbTypeEnum.IN_MEMORY, properties,null,null);
    mgr = factory.createEntityManager();


   String file_to_use = userData;
   SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
   System.out.println("Starting inserts with file "+file_to_use+" at "+sdf.format(Calendar.getInstance().getTime()));

   BufferedReader CSVFile = null;
   try {
        CSVFile = new BufferedReader(new FileReader(file_to_use));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
     String dataRow = null;
    try {
        dataRow = CSVFile.readLine();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } // Read the first line of data.
      int i = 0; 
      while (dataRow != null){
          String[] dataArray = dataRow.split(",");
          User user = new User();
          user.setName(dataArray[0]);
          user.setAge(Integer.parseInt(dataArray[1]));
          user.setLastName(dataArray[2]);
          System.out.println("Inserting Values "+dataArray[0]+" "+dataArray[1]+" "+dataArray[2]);


          mgr.flush();
          try {
            dataRow = CSVFile.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
      }

     java.util.List<User> result;
     System.out.println("#### By LastName ####");
     result = User.findByLastName(mgr, "Freida");
     System.out.println("Result Size: "+ result.size());

     System.out.println("#### By Time ####");
     result = User.findByName(mgr, "John");
     System.out.println("Result Size: "+ result.size());
}
}

用户数据的内容:

John,17,Freida
Jim,18,Freida
Jam,19,Freida
Johny,20,Freida
Jen,21,Freida
4

1 回答 1

1

编辑:这是 PlayOrM 中一个非常具体的错误。已提交的修复程序是最新的https://github.com/deanhiller/playorm/commit/22d50a12667d03fd2c4683abeb59a4822420a4ce

仅当您在同一列上同时使用 @NoSqlPartionedBy 和 @NoSqlIndexed 两次时才会发生这种情况。一种解决方法是在您的 where 子句中放置一些东西(任何东西),它每次都会使用特定的索引(基于您的 where 子句中的列)。或者只是获取带有修复程序的最新代码。

我不确定您是否应该使用分区。在您的示例中,您以两种方式对表进行分区......名称和姓氏。在一种情况下,所有同名的行都在同一个分区中。在另一种情况下,具有相同 lastName 的所有行都在同一个分区中。您只能查询单个分区。所以想象你有名字

dean
mike
joe

这是 3 个不同的分区,您可以查询任何人。您可以查询“给我所有在 partition=dean 中姓氏=smith 的人”,或者您可以查询给我所有姓氏=smith 在 partition=mike 中的人”

想象一下,你也有 lastNames

smith
black
obama

您在这里有 3 个分区,您可以查询“给我所有在 partition=smith 中 name=dean 的人”或“给我所有在 partition=black 中 name=dean 的人”

如果您想让事情变得更容易,请摆脱所有 @NoSqlPartitionByField 以便您根本不进行分区。

基本上,通过分区,您可以查询单个分区。每个分区都是它自己的索引。这就是为什么它可以在您拥有 X 百万行的无限分区时进行扩展。但是,您不能在分区中拥有无限行。

我猜了很多,因为您的示例仅插入一行,而您声称要插入 3 行,我希望您的代码在这两种情况下都返回 1 行。您的查询要求返回 lastName="Frieda" 分区中的所有行,然后返回 name="John" 分区中的所有行,并且由于您存储了两者的对象,因此该行应该最终进入的分区.. ..这对我们来说已经在生产中工作了,我们对此没有任何问题。

让我知道您是否有更多信息,例如执行 3 次插入而不是仅此一次的代码。

院长

于 2013-04-08T17:56:58.547 回答