Список поиска Python объектов, которые содержат объекты, частичные совпадения - PullRequest
0 голосов
/ 28 января 2011

Я пытаюсь создать простую поисковую систему для небольшого сайта.Моя первоначальная мысль - избегать использования более крупных пакетов, таких как Solr, Haystack и т. Д., Из-за упрощенного характера моих поисковых запросов.

Я надеюсь, что с некоторыми указаниями я смогу сделать свой код более питонным, эффективным,и, что самое важное, правильно функционируют.

Предполагаемая функциональность: возвращать результаты продукта на основе полного или частичного совпадения 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 продуктов.

Некоторые вещи, которые бросаются в глаза мне.Гнездится для петель.Два разных оператора if в поиске по продукту, которые могут привести к добавлению в результаты дублированных продуктов.

Я думал, что если бы у меня были продукты в памяти (продукты будут редко меняться), я мог бы их кэшировать, уменьшаязависимость от базы данных и, возможно, обеспечение эффективного поиска.

... публикация на данный момент ... вернется и добавит больше мыслей

Редактировать: причина, по которой у меня есть объект Category, содержащий списокПродукты - это то, что я хочу показать html-страницы продуктов, организованных по категориям.Кроме того, фактические номера категорий могут измениться в будущем, и проведение кортежа казалось простым безболезненным решением.Это и у меня есть доступ только для чтения к базе данных.

Причиной отдельного списка продуктов был какой-то обман.У меня есть страница, которая показывает все продукты с возможностью просмотра MSDS (листы безопасности).Кроме того, он предоставил на один уровень меньше для поиска во время поиска.

Редактировать 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

Ответы [ 2 ]

0 голосов
/ 28 января 2011

Если имя и номер соответствуют параметрам поиска, продукт появится в списке результатов дважды.

Поскольку количество продуктов небольшое, я рекомендую создать запрос 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 голосов
/ 28 января 2011

Подготовьте все переменные вне циклов и используйте 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...