2011-01-28 17 views
0

私は小さなウェブサイト用の簡単な検索エンジンを構築しようとしています。私の最初の考えは、私の検索ニーズの単純な性質のために、Solr、Haystackなどのより大きなパッケージを使用することを避けることです。オブジェクト、部分一致を含むオブジェクトのPython検索リスト

私の希望は、いくつかの指針では、私のコードをもっとpythonic、効率的にすることができ、最も重要なのは適切に機能することです。 ITEM_NUMBER、製品名、またはカテゴリ名の完全または部分的な一致に基づいてリターン製品結果(カテゴリマッチングの現在のところ実装)

一部コード:

 

import pymssql 
import utils #My utilities 

class Product(object): 
    def __init__(self, item_number, name, description, category, msds): 
     self.item_number = str(item_number).strip() 
     self.name = name 
     self.description = description 
     self.category = category 
     self.msds = str(msds).strip() 

class Category(object): 
    def __init__(self, name, categories): 
     self.name = name 
     self.categories = categories 
     self.slug = utils.slugify(name) 
     self.products = [] 

categories = (
    Category('Food', ('123', '12A')), 
    Category('Tables', ('354', '35A', '310', '31G')), 
    Category('Chemicals', ('845', '85A', '404', '325')) 
) 

products = [] 

conn = pymssql.connect(...) 
curr = conn.cursor() 

for Category in categories: 
    for c in Category.categories: 
     curr.execute('SELECT item_number, name, CAST(description as text), category, msds from tblProducts WHERE category=%s', c) 
     for row in curr: 
      product = Product(row[0], row[1], row[2], row[3], row[4]) 
      products.append(product) 
      Category.products.append(product) 

conn.close() 

def product_search(*params): 
    results = [] 
    for product in products: 
     for param in params: 
      name = str(product.name) 
      if (name.find(param.capitalize())) != -1: 
       results.append(product) 
      item_number = str(product.item_number) 
      if (item.number.find(param.upper())) != -1: 
       results.append(product) 
    print results 

product_search('something') 

 

MS SQLデータベース機能が意図

テーブルやフィールドで私は変更することはできません。
ほとんどの場合、約200個の製品を引き取ります。

私に飛びつくものもあります。 forループ用にネストされています。製品の検索に2つの異なるif文が含まれているため、結果に重複した商品が追加される可能性があります。

私の考えでは、メモリに製品があれば(ほとんど変更されません)、キャッシュできるためデータベースの依存性が軽減され、効率的な検索が可能です。今の投稿

は... ...戻ってきて、より多くの思考

を追加します

編集: 私は製品のリストを保持するCategoryオブジェクトを持っている理由は、私が組織製品のhtmlページを表示したいということですカテゴリ別。また、実際のカテゴリ番号は将来変化し、タプルを保持するのは簡単な解決策のように思えます。それと私はデータベースへの読み取り専用アクセス権を持っています。

製品の別のリストの理由は、多分不正行為でした。私は、MSDS(安全シート)を見ることができるすべての製品を示すページを持っています。また、検索中に横断するレベルが1つ低くなりました。

編集2:

 

def product_search(*params): 
    results = [] 
    lowerParams = [ param.lower() for param in params ] 

    for product in products: 
     item_number = (str(product.item_number)).lower() 
     name = (str(product.name)).lower() 
     for param in lowerParams: 
      if param in item_number or param in name: 
       results.append(product) 
    print results 
 

答えて

0

は、ループの外にすべての変数を用意し、ストリングの位置を必要としない場合は代わりに.findinを使用します。

def product_search(*params): 
    results = [] 
    upperParams = [ param.upper() for param in params ] 

    for product in products: 
     name = str(product.name).upper() 
     item_number = str(product.item_number).upper() 
     for upperParam in upperParams: 
      if upperParam in name or upperParam in item_number: 
       results.append(product) 
    print results 
+0

製品名は大文字であるが、ITEM_NUMBERは、常にすべて大文字で、おそらく番号が含まれています。たとえば、item_number = 147DECAFです。だから、私は名前とitem_numberを区別する必要があると思う。 – Chris

+0

'' 147DECAF "'を 'str()'する必要はありません。文字列のように見えます。 – eumiro

+0

誰かが147を検索した場合、それは整数ではありませんか? 147DECAF、147CAF、147BLAHなど – Chris

0

名の両方の場合番号が検索パラメータと一致すると、製品は結果リストに2回表示されます。

製品は少数で数えるので、私は同じようSELECTクエリを構築するお勧めします。

def search(*args): 
    import operator 
    cats = reduce(operator.add, [list(c.categories) for c in categories], []) 

    query = "SELECT * FROM tblProducts WHERE category IN (" + ','.join('?' * len(cats)) + ") name LIKE '%?%' or CAST(item_number AS TEXT) LIKE '%?%' ..." 
    curr.execute(query, cats + list(args)) # Not actual code 
    return list(curr) 
+0

さて、実際のテーブル(tblProducts)には何千ものレコードが含まれています。これは、非常に時間がかかるクエリではなく、既存のオブジェクトにクエリを実行しようとしていた理由です。 – Chris

+0

また、 'products'リストには何千ものレコードがメモリに格納されます。あなたができる最良のことは、実際にこのようなクエリにどれくらいの時間がかかるかを実際に測定することです。 – vz0

+0

何千ものレコードが含まれているのはなぜですか?私のSQLクエリでは、私は定義されたカテゴリに一致するテーブルから製品を引っ張っているだけです。 – Chris

関連する問題