2011-01-28 3 views
0

작은 웹 사이트에 간단한 검색 엔진을 구축하려고합니다. 나의 초기 생각은 Solr, Haystack 등과 같은 더 큰 패키지를 사용하지 않는 것이다. 왜냐하면 나의 검색 요구가 단순하다는 특성 때문이다.개체, 부분 일치를 포함하는 개체의 파이썬 검색 목록

제 희망은 좀 더 파이썬적이고 효율적이며 가장 중요한 기능을 제대로 수행 할 수 있기를 바랍니다.

의도 된 기능 :

 

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 데이터베이스 : 전체 또는 부분 ITEM_NUMBER의 일치, 제품 이름 또는 카테고리 명 (카테고리 매칭의 현재 구현이)

일부 코드를 기반으로 반환 제품 결과 테이블과 필드가 있으면 변경할 수 없습니다.
최대 약 200 개 제품을 가져옵니다.

나에게 뛰어 오는 것들. for 루프에 중첩됩니다. 제품 검색에서 두 개의 서로 다른 if 문으로 인해 중복 제품이 결과에 추가 될 수 있습니다.

내 생각에 내가 제품을 메모리에 저장하면 (제품이 거의 변경되지 않음) 데이터베이스를 저장하고 효율적인 검색을 제공하여 캐시 할 수 있다고 생각했습니다. 지금 게시

는 ... ... 다시 와서 더 생각

을 추가합니다

편집 : 내가 제품의 목록을 들고 카테고리의 객체를 가지고있는 이유는 내가 조직 제품의 HTML 페이지를 표시 할 것입니다 카테고리별로. 또한 실제 범주 번호는 미래에 변경 될 수 있으며 튜플을 유지하는 것은 간단한 고통없는 솔루션처럼 보입니다. 저와 나는 데이터베이스에 대한 읽기 전용 권한을 가지고 있습니다.

제품 목록이 별도 인 이유는 속임수였습니다. MSDS (안전 시트)를 볼 수있는 모든 제품을 보여주는 페이지가 있습니다. 또한 검색하는 동안 트래버스하기위한 레벨이 한 단계 줄어 들었습니다.

편집 2 :

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

는 루프의 외부 변수를 모두 준비하고 대신 .findin를 사용 번호가 검색 매개 변수와 일치하면 제품이 결과 목록에 두 번 나타납니다.

제품, 나는 같은 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

제품 이름은 대문자로되어 있지만, ITEM_NUMBER은 항상 모두 대문자이고 아마도 번호가 포함되어 있습니다. 예를 들어 item_number = 147DECAF입니다. 그래서 나는 * name과 item_number를 구분할 필요가 있다고 생각한다. – Chris

+0

당신은''str()''에''147DECAF "'를 써서는 안됩니다 - 그것은 이미 문자열처럼 보입니다. – eumiro

+0

누군가가 147을 검색하면 정수가 아닐까요? 147DECAF, 147CAF, 147BLAH 등 – Chris

0

모두 이름 경우 : 당신은 문자열의 위치가 필요하지 않은 경우

 

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

글쎄, 실제 테이블 (tblProducts) 수천 개의 레코드가 들어 있습니다. 이것이 내가 시간을 많이 소비하는 쿼리를 수행하는 대신 기존 개체를 쿼리하려고했던 이유입니다. – Chris

+0

그러면'products'리스트에는 수천 개의 레코드가 메모리에 저장됩니다. 당신이 할 수있는 가장 좋은 일은 실제로 얼마나 많은 시간이 걸리는지를 측정하는 것입니다. – vz0

+0

수천 개의 레코드가 왜 포함되어 있습니까? 내 SQL 쿼리에서 나는 정의 된 범주와 일치하는 테이블의 제품만을 가져옵니다. – Chris