0

小さなウェブサイト用のシンプルな検索エンジンを構築しようとしています。私の最初の考えは、Solr、Haystack などのより大きなパッケージの使用を避けることでした。これは、私の検索ニーズが単純化されているためです。

私の希望は、いくつかのガイダンスにより、コードをより 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 ステートメントにより、重複した製品が結果に追加される可能性があります。

私が考えたのは、メモリ内に製品があれば (製品はめったに変更されない)、それらをキャッシュして、データベースへの依存を減らし、効率的な検索を提供できる可能性があるということでした。

...今のところ投稿しています...戻ってきて、さらに考えを追加します

編集: 製品のリストを保持するカテゴリ オブジェクトがある理由は、カテゴリ別に整理された製品の 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

4

2 に答える 2

0

部分文字列の位置が必要ない場合は、ループの外側ですべての変数を準備し、in代わりに使用します。.find

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
于 2011-01-28T14:29:59.673 に答える
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)
于 2011-01-28T14:30:27.613 に答える