2016-04-08 7 views
0

投影される属性の等価条件を許可しないNoSQLデータベースを使用しています。たとえば、select a from table where a > 10などの不等式操作は可能ですが、select a from table where b < 10は許可されますが、select a from table where a = 10は許可されません。もちろん私の場合は平等を使用する必要があるので、平等操作を不等式操作に変えたいと思います。文字列の前後の値を取得する

私は電子メールでレコードを取得する必要があります。もし私がselect email from table where email = '[email protected]'に行くことができますが、これは許可されていませんので、私は[email protected]の直前に辞書編集的な値を与えたいとしています。文はまだ[email protected]を返します

select email from table where email < [1 value above] and email > [1 value below] 

この方法:だから、クエリは次のようになります。私はこれを達成する方法にも問題があります。

通常、文字列を比較するには、どちらか大きい方と小さい方を確認するために"[email protected]".compare("[email protected]")に行ってください。この方法は、辞書編集に基づいて何とか値を比較しますが、どのようにしますか?私の質問は、文字列の直下の辞書編集的な値と、文字列の直後の辞書編集的な値を取得する方法です。

+4

NoSQLは「<' and '>」をサポートしますが、「=」はサポートしていません。 – Andreas

+0

@Andreas Google Datastore - 投影クエリを使用している場合、等価フィルタ条件で使用している属性を投影することはできません。 https://cloud.google.com/appengine/docs/python/datastore/projectionqueries – user2924127

+0

NoSQLのこの謎の味は、「NOT」演算子をサポートしていますか?なぜ、Tからselect(*電子メール<:val or email>:val) 'をしないのですか? – nbrooks

答えて

1

文字列の直後の文字列は簡単です。それは'\0'は、可能な限り低いchar値であるので、この作品だけ

str + '\0' 

です。

すぐに文字列の前に、strの前に文字列がよりトリッキーです。文字列が'\0'で終わる場合は、それを削除することができます。文字列が'\0'で終わらない場合は、重大な問題があります。例として、文字列"foo"を考えてみましょう。

以下の文字列のそれぞれは、"foo"以下であり、それぞれが最後よりも大きいです。 "foo"未満

"fon" + Character.MAX_VALUE; 
"fon" + Character.MAX_VALUE + Character.MAX_VALUE; 
"fon" + Character.MAX_VALUE + Character.MAX_VALUE + Character.MAX_VALUE; 
... 

最大String値は"fon"(これは権利ではないかもしれない。私はchar[]の可能な最大長さが何であるかわからないんだけど)Character.MAX_VALUE2^31 - 4コピーのようなものが続いています。しかし、そのような文字列をメモリに格納することはできません。

したがって、問題の別の解決策を見つけようとする必要があります。あなたのアルファベットがa-z0-9で、大文字と小文字を区別しない、あなたはベース36数としてあなたの文字列を扱うことができますし、単に単純な算術を使用して値をデクリメント/インクリメントと仮定すると、

+1

説明をありがとう! – user2924127

1

JavaのLong.valueOfメソッドを使用すると、指定された基数でStringを取得し、その基数(基数10)Longに変換できます。 Longインスタンスを取得したら、1を加算して次の値を取得するだけです。

public static String nextString(String str) { 
    return Long.toString(Long.valueOf(norm(str), 36) + 1, 36); 
} 

操作を逆にするには、あなたはlongインスタンスを受け取り、指定された基数で、String表現に変換Long.toString方法を、使用することができます。だからあなたはあなたの基底を表現することができます。longは、基数36の数字として、a-zという文字を含みます。

public static String prevString(String str) { 
    return Long.toString(Long.valueOf(norm(str), 36) - 1, 36); 
} 

あなたはこれらのメソッドを使用しているとき、あなたの文字列を正規化したいと思うので、これは、私たちの無効な文字をフィルタリングし、すべてが小文字であることを確認し、NULLポインタ例外または番号形式の例外を防ぐことができます。

private static String norm(String str) { 
    if (str == null) { 
     return "0"; 
    } 
    return str.toLowerCase().replaceAll("[^a-z0-9]", ""); 
} 
関連する問題