2016-09-23 16 views
5

के लिए आंशिक अनुक्रमणिका बनाएं I postgresql jsonb कॉलम में आंशिक अनुक्रमणिका जोड़ने की कोशिश कर रहा हूं। जेसनबी कॉलम का नाम है: ईमेल_प्रोवाइडर। मैंने नीचे दिखाए गए कॉलम पर आंशिक अनुक्रमणिका जोड़ने का प्रयास किया है, लेकिन यह पीजी :: अपरिभाषित कॉलम: त्रुटि: कॉलम "ईमेल_पोविडर" मौजूद नहीं है और दूसरी बार यह त्रुटि उठाता है: पीजी :: अस्पष्ट कार्य : त्रुटि: ऑपरेटर अद्वितीय नहीं है: -:postgresql jsonb फ़ील्ड

add_index :accounts, :name, name: "index_accounts_on_email_provider_kind", using: :gin, where: "('email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com') AND ('email_povider' -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com')" 

email_provider स्तंभ के लिए json इस तरह दिखता है:

अज्ञात रेल -5 प्रवास इस तरह दिखता में> अज्ञात

आंशिक सूचकांक

{ 
    "email_provider": { 
    "sparkpost": { 
     "smtp_host": "www.sparkpost.com", 
     "smtp_port": "" 
     }, 
     "aws ses": { 
     "smtp_host": "www.amazon/ses.com ", 
     "smtp_port": " ", 
     "username": " ", 
     "password": " " 
     } 
    } 
} 

तालिका इस प्रकार है:

class CreateAccounts < ActiveRecord::Migration[5.0] 
    def change 
     create_table :accounts do |t| 
     t.string :name, null: false 
     t.jsonb :email_provider, null: false 
     t.jsonb :social_account, default: '[]', null: false 
     t.timestamps 
    end 
     add_index :accounts, :name, name: "index_accounts_on_email_provider_kind", using: :gin, where: "('email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com') AND ('email_povider' -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com')" 

     add_index :accounts, :name, name: "index_accounts_on_social_account_type", using: :gin, where: " 'social_account' @> [{'type': 'facebook'}] AND 'social_account' @> [{'type': 'twitter'}]" 
    end 
end 

अद्यतन

नीचे स्वीकार किए जाते हैं जवाब देने के लिए मामूली समायोजन के आधार पर, कोड मैं BTREE नहीं जिन बनाने के लिए सूचकांक उपयोग कर रहा हूँ रेल में activerecord नीचे दिखाया गया है।

add_index :accounts, :name, name: "index_accounts_on_name_email_provider", where: "email_provider -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com' AND email_provider -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com' " 

add_index :accounts, :name, name: "index_accounts_on_name_social_account", where: " social_account @> '[{\"type\": \"facebook\"}]'::jsonb AND social_account @> '[{\"type\": \"twitter\"}]'::jsonb" 

उत्तर

9

मैं तुम्हें ऐसा ही कुछ की जरूरत है:

add_index :accounts, :email_provider, name: "index_accounts_on_email_provider_kind", using: :gin, where: "(email_provider -> 'email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com') AND (email_provider -> 'email_povider' -> 'amazon ses' ->> 'smtp_host' = 'www.awses.com')" 

मैं यह एक BTREE सूचकांक क्योंकि हम नाम स्तंभ स्ट्रिंग डेटाप्रकार की है और नहीं जो प्रयोग कर रहे हैं के रूप में वर्णित here jsonb बनाता है मैंने add_index से :email_provider के दूसरे तर्क को बदल दिया क्योंकि यह कॉलम नाम है। इसके अलावा, where खंड के लिए, मैं

'email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com' 

बदल

email_provider -> 'email_provider' -> 'sparkpost' ->> 'smtp_host' = 'www.sparkpost.com' 

क्योंकि -> ऑपरेटर यह तर्क छोड़ दिया एक json (ख) मूल्य होने की उम्मीद करने के लिए, लेकिन आप एक स्ट्रिंग प्रदान की। तो उदा। email_provider -> 'email_provider'email_provider नामक कॉलम से email_provider से संबंधित मान निकालता है। #>> जो एक josn (ख) वस्तु से एक "पथ" के अर्क का उपयोग करके

email_provider #>> '{email_provider,sparkpost,smtp_host}' = 'www.sparkpost.com' 

: ध्यान दें कि यह अंतिम पंक्ति के रूप में अधिक दृढ़तापूर्वक लिखा जा सकता है। तो add_index बयान लिखा जा सकता है के रूप में:

add_index :accounts, :email_provider, name: "index_accounts_on_email_provider_kind", using: :gin, where: "(email_provider #>> '{email_provider,sparkpost,smtp_host}' = 'www.sparkpost.com') AND (email_provider -> '{email_povider,amazon ses,smtp_host}' = 'www.awses.com')" 

आप दूसरे सूचकांक के लिए, आप की तरह कुछ प्रयास करना चाहिए:

where: " social_account -> 'social_account' @> '[{\"type\": \"facebook\"}]'::jsonb AND social_account -> 'social_account' @> '[{\"type\": \"twitter\"}]'::jsonb" 

इस मामले में, मैं एक ही स्तंभ के साथ पहली बार में के रूप में सोचा मामला। मैंने @> का सही तर्क भी बदल दिया, जिसे एक jsonb मान होना चाहिए। तो आपको इसे एक JSON स्ट्रिंग के रूप में परिभाषित करना होगा, जिसके लिए तारों के लिए डबल कोट्स की आवश्यकता होती है (यह भी ध्यान दें कि हमें उन्हें रूबी के लिए बचाना है), और फिर वांछित प्रकार प्राप्त करने के लिए उस स्ट्रिंग को jsonb पर डालें।

+0

धन्यवाद मैं इसे आजमाउंगा और आपको वापस ले जाऊंगा। लेकिन मैं इंडेक्स को ** नाम कॉलम ** पर रखूंगा, भले ही jsonb कॉलम ** ईमेल प्रदाता ** है क्योंकि इंडेक्स ** नाम कॉलम ** पर ** और ** ** क्वेरी तेज होगी जहां क्वेरी ** का उपयोग हमारे इंडेक्स को जेसनबी कॉलम से मैचों तक सीमित करने के लिए किया जाता है। आप देख सकते हैं कि उस दृष्टिकोण को यहां समझाया गया है: http://blog.heapanalytics.com/speeding-up-postgresql-queries-with-partial-indexes/। – brg

+0

बहुत धन्यवाद। मैंने इंडेक्स को ** नाम कॉलम ** पर रखा है। एकमात्र परिवर्तन ** का उपयोग कर निकालना था:: जीन ** क्योंकि इंडेक्स सीधे जेसनबी कॉलम पर नहीं है। इसलिए इंडेक्स में से किसी एक के लिए अंतिम कोड इस तरह दिखता है: ** add_index: accounts,: name, name: "index_accounts_on_name_email_provider", जहां: "(email_provider -> 'email_provider' -> 'स्पार्कपोस्ट' - >> 'smtp_host' = ' www.sparkpost.com ') और (email_provider ->' email_povider '->' अमेज़ॅन सेस '- >>' smtp_host '=' www.awses.com ') "**, जो ** btree आंशिक अनुक्रमणिका बनाता है ** ** नाम कॉलम ** पर jsonb कॉलम में विशेषताओं के लिए हमारे मैचों को प्रतिबंधित करना। – brg

संबंधित मुद्दे