6

MySQL から MongoDB に大量のデータをインポートする必要があり、(既存のデータのように) 別のキー/値に格納する代わりに、ObjectID からのタイムスタンプを使用したいと考えています。これを行うには、過去の日付で既存のデータの ObjectID を作成する必要があります。PHPドライバーを使用してこれを行う必要もあります。Python、Java、Node.JSでこれを行う方法があるかもしれないと読んだので、PHPにも同等の方法があるのではないかと思いました。

これが可能であれば、安全に実行できますか? つまり、重複または無効な ObjectID で問題が発生しますか? ありがとう。

Node.JS の場合:

var timestamp = Math.floor(new Date().getTime()/1000);
var objectId = new ObjectID(timestamp);

以下は次のとおりです:タイムスタンプを使用してソートする MongoDB

Python の場合:

gen_time = datetime.datetime(2010, 1, 1)
dummy_id = ObjectId.from_datetime(gen_time)

Java の場合:

Date d = new Date(some timestamp in ms);
ObjectId id = new ObjectId(d)
4

3 に答える 3

11

現在、PHP ドライバーにはこのための機能が組み込まれていません。他の回答で言及されている __set_state() は、ID をセッションで逆シリアル化できるようにするためのものであり、特定のコンポーネントを介して ID を作成することはできません。

ID を自動的に作成するには、次の手順を実行する必要があります。

<?php
function createId( $yourTimestamp )
{
    static $inc = 0;

    $ts = pack( 'N', $yourTimestamp );
    $m = substr( md5( gethostname()), 0, 3 );
    $pid = pack( 'n', posix_getpid() );
    $trail = substr( pack( 'N', $inc++ ), 1, 3);

    $bin = sprintf("%s%s%s%s", $ts, $m, $pid, $trail);

    $id = '';
    for ($i = 0; $i < 12; $i++ )
    {
        $id .= sprintf("%02X", ord($bin[$i]));
    }
    return new MongoID($id);
}

var_dump( createId( time() ) );
?>
于 2013-01-17T13:23:21.443 に答える
7

比較のためだけにMongoIdを使用している場合、たとえば、日付範囲内のすべてのレコードを選択する場合、完全に有効なIDは必要ありません。だからあなたは簡単に行うことができます:

$id = new \MongoId(dechex($timestamp) . str_repeat("0", 16));

このIDは絶対に挿入せず、$ gte / $ gt / $ lt /$lteクエリに使用してください。

編集

残念ながら、上記のスニペットは1979年以前の日付でdechex($timestamp)機能し、常に8文字を返すとは限らないため、より適切なスニペットは次のようになります。

$id = new \MongoId(sprintf("%08x%016x", $timestamp, 0));
于 2013-03-12T13:18:11.310 に答える
0

objectid を一意にする要因の 1 つは時刻の部分ですが、複数の挿入で同時に最後のバイト (またはその前後) をインクリメントする必要があるため、これにより問題が発生する可能性があります。

ObjectId をいくつかのパラメーターで作成できるようにする動きがあったようですが、実際には、ここでほとんど話しています: http://php.net/manual/en/mongoid.set-state.php

理論的には、新しい ID を作成するために使用されるプロパティの配列です。ただし、MongoId インスタンスにはプロパティがないため、これは使用されません。

ObjectIdただし、独自のジェネレーターを作成せずに、他の言語でできることを達成する方法はありません。

于 2013-01-17T10:08:34.123 に答える