2016-04-13 24 views
0

PostgreSQL ile bir Rails uygulamasına sahibim.Etkili bir gevşeklik alt etki alanı adı önerisi uygulama

Kullanıcı girdisi önceden seçilmişse, belirli bir kaynağa alternatif adlar önermek için bir yöntem uygulamaya çalışıyorum.

Benim referans gevşek geçerli: verimli bir şekilde yapmak herhangi bir çözüm

slack domain input

var mı? verimli İçin

Yani: sorguları arasında tek veya ayrıca küçük seti kullanılarak. Yine de bir saf SQL çözümü harika olurdu.

Benim ilk uygulama aşağıdaki gibi görünüyordu:

def generate_alternative_names(model, column_name, count) 
    words = model[column_name].split(/[,\s\-_]+/).reject(&:blank?) 
    candidates = 100.times.map! { |i| generate_candidates_using_a_certain_strategy(i, words) } 
    already_used = model.class.where(column_name => candidates).pluck(column_name) 
    (candidates - already_used).first(count) 
end 

# Usage example: 
model = Domain.new 
model.name = 'hello-world' 
generate_alternative_names(model, :name, 5) 
# => ["hello_world", "hello-world2", "world_hello", ...] 

Daha sonra, 100 aday üretir maçları için veritabanını kontrol eder ve adayların listeden kaldırır. Sonunda ayıklanan ilk count değerlerini döndürür.

Bu yöntem, az sayıda çakışmaya (benim durumumda 100 çakışma) sahip küçük öneri kümeleri için çalıştığı için en iyi efor uygulaması'dur.

Bu sihirli sayıyı artırsam bile (100), süresiz ölçeklenmez.

Bunu geliştirmek için bir yöntem biliyor musunuz, bu yüzden çok sayıda çakışma ve büyü numaralarını kullanmadan ölçeklenebilir mi?

+0

Sizin yönteminiz, tek bir "nerede ... in" sorgusu kullanır. Veritabanına tam olarak bir kere vurur **. Ne istediğinden emin değilim, ama bunu yapmak için hazır bir Gem ise, bu Stack Overflow'ta konu dışıdır. – meagar

+0

Elbette meagar, ancak çözüm sadece çakışmalar 100'ün altındaysa işe yarar. Daha fazla aday oluştursam bile, süresiz olarak ölçeklenmez. Eminim daha iyi yöntemler vardır. :) – ProGM

cevap

2

Ben ters bir yaklaşımla giderdim: LIKE kullanarak mevcut kayıtları için veritabanını sorgulamak ve daha sonra zaten alınmış atlama önerileri oluşturmak:

def alternatives(model, column, word, count) 
    taken = model.class.where("#{column} LIKE '%#{word}%'").pluck(column) 
    count.times.map! do |i| 
    generate_candidates_using_a_certain_strategy(i, taken) 
    end 
end 

Atlanacak zaten alınmış kelimelerin dizisi alır bir generate_candidates_using_a_certain_strategy olun. Aynı ismi alan iki istekte yarış durumuyla ilgili olası bir aksaklık olabilir, ancak herhangi bir soruna neden olabileceğini düşünmüyorum, çünkü gerçek bir yaratım başarısız olduğunda her zaman özür dilemekte özgürsünüz.

+0

İlginç bir çözüm. Belki de daha fazla adayı eşleştirmek için (örneğin, '' '' '' '' '' '' '' '' '' '' '' ayırıcı olarak '' '' 'yerine' 'NOT LIKE' (bir regexp kullanarak) yerine 'NOT RLIKE' kullanarak geliştirebilirim. – ProGM

+0

Elbette, bu sadece bir başlık/yön, tam bir çözüm değil. – mudasobwa

+0

@SergioTulentsev Oh, uh, gerçekten :) 'DEĞİL 'gereksizdir. – mudasobwa

İlgili konular