sql >> データベース >  >> NoSQL >> Redis

再検索集計は、各グループの上位5つを返します

    最初:

    • 使用しない機能を必ず無効にしてください( NOOFFSETS NOHL NOFREQS STOPWORDS 0
    • SORTABLEを使用する NUMERICの場合 スコア

    テストに使用したスキーマは次のとおりです。

    FT.CREATE product_tags NOOFFSETS NOHL NOFREQS STOPWORDS 0
        SCHEMA product_name TEXT tags TAG score NUMERIC SORTABLE
    

    FT.AGGREGATEについて考えたい パイプラインとして。

    最初のステップは、製品を@scoreで並べ替えることです。これにより、後でパイプラインで REDUCE TOLIST 1 @product_nameを実行します。 、リストは並べ替えられて表示されます:

    SORTBY 2 @score DESC
    

    すでにLOADを実行していると思います /適用 TAGとしてタグを処理します それ以外の場合、フィールドは、製品ごとに、完全なコンマ区切りの文字列タグリストによってグループ化されます。タグフィールドの問題でGROUPBYを許可するを参照してください。したがって、次のステップはパイプラインです:

    LOAD 1 @tags 
    APPLY split(@tags) as TAG 
    

    次に、@ TAGでグループ化し、2つの削減を適用します。私たちの製品リストはソートされて出てきます。

    GROUPBY 1 @TAG
        REDUCE SUM 1 @score AS total_score
        REDUCE TOLIST 1 @product_name AS products
    

    最後に、 @total_scoreで並べ替えます :

    SORTBY 2 @total_score DESC
    

    コマンドの最終ビューは次のとおりです。

    FT.AGGREGATE product_tags *
        SORTBY 2 @score DESC 
        LOAD 1 @tags 
        APPLY split(@tags) as TAG
        GROUPBY 1 @TAG
            REDUCE SUM 1 @score AS total_score 
            REDUCE TOLIST 1 @product_name AS products
        SORTBY 2 @total_score DESC
    

    ここに結果を説明するためのコマンドの完全なリストがあります。 productXXを使用しました スコアXX 製品の分類を視覚的に簡単に確認できます。

    > FT.CREATE product_tags NOOFFSETS NOHL NOFREQS STOPWORDS 0 SCHEMA product_name TEXT tags TAG score NUMERIC SORTABLE
    OK
    > FT.ADD product_tags pt:product10 1 FIELDS product_name product10 tags tag2,tag3,tag4 score 10
    OK
    > FT.ADD product_tags pt:product1 1 FIELDS product_name product1  tags tag1,tag2,tag3 score 1
    OK
    > FT.ADD product_tags pt:product100 1 FIELDS product_name product100 tags tag2,tag3 score 100
    OK
    > FT.ADD product_tags pt:product5 1 FIELDS product_name product5 tags tag1,tag4 score 5
    OK
    > FT.SEARCH product_tags *
    1) (integer) 4
    2) "pt:product5"
    3) 1) "product_name"
       2) "product5"
       3) "tags"
       4) "tag1,tag4"
       5) "score"
       6) "5"
    4) "pt:product100"
    5) 1) "product_name"
       2) "product100"
       3) "tags"
       4) "tag2,tag3"
       5) "score"
       6) "100"
    6) "pt:product1"
    7) 1) "product_name"
       2) "product1"
       3) "tags"
       4) "tag1,tag2,tag3"
       5) "score"
       6) "1"
    8) "pt:product10"
    9) 1) "product_name"
       2) "product10"
       3) "tags"
       4) "tag2,tag3,tag4"
       5) "score"
       6) "10"
    > FT.AGGREGATE product_tags * SORTBY 2 @score DESC LOAD 1 @tags APPLY split(@tags) as TAG GROUPBY 1 @TAG REDUCE SUM 1 @score AS total_score REDUCE TOLIST 1 @product_name AS products SORTBY 2 @total_score DESC
    1) (integer) 4
    2) 1) "TAG"
       2) "tag2"
       3) "total_score"
       4) "111"
       5) "products"
       6) 1) "product100"
          2) "product10"
          3) "product1"
    3) 1) "TAG"
       2) "tag3"
       3) "total_score"
       4) "111"
       5) "products"
       6) 1) "product100"
          2) "product10"
          3) "product1"
    4) 1) "TAG"
       2) "tag4"
       3) "total_score"
       4) "15"
       5) "products"
       6) 1) "product10"
          2) "product5"
    5) 1) "TAG"
       2) "tag1"
       3) "total_score"
       4) "6"
       5) "products"
       6) 1) "product5"
          2) "product1"
    

    上位5つだけでなく、並べ替えられた製品の完全なリストを取得しています。複雑さに関しては、違いはありません。価格を支払いました。影響は、バッファリング、ネットワークペイロード、およびクライアントにあります。

    Luaスクリプトを使用して上位5つに制限できます:

    eval "local arr = redis.call('FT.AGGREGATE', KEYS[1], '*', 'SORTBY', '2', '@score', 'DESC', 'LOAD', '1', '@tags', 'APPLY', 'split(@tags)', 'as', 'TAG', 'GROUPBY', '1', '@TAG', 'REDUCE', 'SUM', '1', '@score', 'AS', 'total_score', 'REDUCE', 'TOLIST', '1', '@product_name', 'AS', 'products', 'SORTBY', '2', '@total_score', 'DESC') \n for i=2,(arr[1]+1) do \n arr[i][6] = {unpack(arr[i][6], 1, ARGV[1])} \n end \n return arr" 1 product_tags 5
    

    上記のLuaスクリプトのわかりやすいビュー:

    local arr = redis.call('FT.AGGREGATE', KEYS[1], ..., 'DESC')
    for i=2,(arr[1]+1) do 
        arr[i][6] = {unpack(arr[i][6], 1, ARGV[1])}
    end
    return arr
    

    1つのキー(インデックス)と1つの引数(上位の製品の制限、あなたの場合は5)を渡します: 1 product_tags 3

    これにより、影響をバッファリングのみに限定し、ネットワークペイロードとクライアントの負荷を節約しました。




    1. StackExchange.Redisとの並列実行?

    2. WindowsでMongoDBに接続するにはどうすればよいですか?

    3. mongoDBの文字列フィールド値の長さ

    4. MapReduceのHadoopマッパークラスとは何ですか?