2010-02-28 8 views
9

Estoy mirando para construir una potente función de búsqueda de un sitio, de forma similar a la búsqueda del desglose de NewEgg, por ejemplo,Diseño del modelo por Drilldown/búsqueda Filtrado

http://www.newegg.com/Product/ProductList.aspx?Submit=ENE&N=2010150014%201035507776&name=7200%20RPM

Estoy trabajando con una variedad de objetos similar a los productos que tienen diferentes criterios. ¿Alguien puede recomendar un buen diseño para construir un motor de búsqueda como NewEgg's?

+0

¿Qué es exactamente una búsqueda desglose? ¿Uno donde puedes buscar dentro de los resultados? Por favor especifique los criterios que (en su opinión) son necesarios para una buena búsqueda. –

+0

Un conjunto de elementos tiene atributos únicos que se pueden buscar en contra. Por ejemplo, con un disco duro puede filtrar por RPM (5400, 7200, 10,000, etc.) pero con un monitor puede filtrar por tamaño de pantalla (17 ", 19", 22 ", etc.). Cada elemento tiene un conjunto diferente de las propiedades que se pueden filtrar contra que pueden ser exclusivas para el tipo de elemento. –

Respuesta

20

Almacenar los datos "verticalmente", es decir, en un formato Entity-Attribute-Value (EAV), junto con la gestión de esquemas metadatos basada en datos implícita a EAV, proporcionar un marco donde los atributos de cada producto son "independientes" entre sí . Esto, a su vez, facilita la implementación del desglose (es decir, el refinamiento guiado de la consulta, donde en cada paso se proporciona al usuario final la lista de posibles atributos aún aplicables, para cada atributo tal la lista de valores posibles).

Una pequeña advertencia es que esto es mejor aplicable a catálogos más pequeños (digamos menos de 1 millón de productos), porque el modelo EAV puede presentar algunos problemas de rendimiento y escalabilidad con bases de datos más grandes. El tamaño real al cual el rendimiento es una preocupación varía con los detalles del catálogo (número promedio de atributos por producto, características comunes de los atributos de un tipo diferente, complejidad general de la "ontología", etc.), pero EAV es bastante el camino a seguir para catálogos más pequeños. Además de su compatibilidad con el filtrado "detallado", introduce un esquema de datos flexible (capacidad de agregar/eliminar atributos y/o tipos de productos, etc., sin requerir un cambio en el esquema físico (base de datos); solo el esquema lógico es alterado).

Editar: más información/recursos en EAV
Es cierto que el artículo de Wikipedia sobre él es algo abstracta ...
En pocas palabras, el modelo identifica los siguientes conceptos:

  • Entidad (también conocido como un producto, o un artículo) = un "registro" en la jerga relacional tradicional
  • Atributo = una "columna" (también conocido como "campo") en la jerga RDBMS
  • Valor = la n valor numérico (o cadena u otro) de una columna dada para un registro dado.
  • Escriba (aka category) = [vagamente] una "tabla" en RDBMS, es decir, un conjunto de registros que comparten, generalmente, el mismo conjunto de atributos.

Para ilustrar esto con, por ejemplo, un catálogo de productos electrónicos, una entidad podría ser un "Monitor de pantalla plana", su Tipo podría ser "Dispositivos de visualización", sus atributos "Tamaño", "Resolución", " Precio", etc.

Con EAV, la mayor parte de la información se almacena en dos tablas llamadas decir la tabla de productos, y la mesa ProductAttributes:

Product table 
    "ProductID" (primary key, the "EntityId") 
    "TypeId" 
    optionally, some common attributes found in all/most other Products, say... 
     price 
     ManufacturerId 
     Photo 

ProductAttributes table 
    "ProductID" (Foreign Key to Product table) 
    "AttributeID" (FK to Attribute table) 
    "Value" (actual value; note: sometimes we can have several SQL fields for 
       this say IntValue, StringValue, DateValue, allowing to store 
       values in their natural format) 

las tablas anteriores constituyen el grueso de los datos, y se complementa con tablas que almacenan el [lógico] esquema del catálogo, también conocido como los "metadatos". Estas tablas incluyen:

  • Tabla de atributos donde se definen los atributos: nombre, tipo de datos, es necesario y tal.
  • Tipos Tabla donde se definen los tipos (categorías): Nombre, posiblemente tipo principal en el caso de ontologías jerárquicas.
  • Type_Attributes donde se enumeran los atributos posibles para un tipo dado (por ejemplo: un "TV Set" tiene el atributo "Number of channels", "Screen Size" etc. y un "VCR" tiene el atributo "Number of Heads", " formato compatible", 'Color del cuerpo', etc.

Todo esto puede parecer algo complicado, en comparación con el enfoque tradicional mediante el cual el esquema lógico es 'codificado' dentro del esquema de SQL, es decir, tenemos una 'TVsets' tabla su conjunto de columnas una por atributo, y luego una tabla "VCR" con su propio conjunto diferente de columnas/atributos. Sin embargo, con ese enfoque, la lógica de la aplicación termina codificando de alguna manera (aunque solo sea mediante una indirección en un mapa de géneros) los nombres de la tabla y columna.
Por el contrario, el modelo EAV permite que el programa descubra la lista de tipos posibles y, para cada tipo, la lista de posibles atributos (obligatorios u opcionales). Además, dado que los valores de los atributos se almacenan todos en la misma tabla, es posible filtrar los atributos independientemente del tipo (o subtipo) del producto. Por ejemplo, para que todos los artículos sean más baratos que 50 dólares (en el otro enfoque, puede que hayamos tenido que buscar en docenas de tablas para eso).

Volver a la característica de "drill-down" ...
Una vez que se realiza una búsqueda inicial (digamos buscar todos los productos en nombre de [indexada] contiene la palabra "pantalla"), la tabla puede producir ProductAttributes la lista distinta de todos los diferentes AttributeID (por lo tanto, nombre de atributo por búsqueda en la tabla de atributos) para productos que satisfagan este primer criterio de búsqueda.
Cuando el usuario selecciona un atributo determinado (por ejemplo, "Fabricante", la tabla ProductAttributes puede generar una lista distinta de fabricantes (junto con la cantidad de productos para cada fabricante). Alternativamente, dicha información se puede buscar inicialmente en lugar de el usuario lo solicita)
El usuario selecciona un fabricante determinado (o varios), y se ejecuta una nueva consulta para reducir la lista de resultados iniciales. La lista de posibles atributos (y dentro de cada atributo la lista de posibles valores) disminuye, ya que algunos productos (entidades) inicialmente seleccionados ahora están excluidos.
El proceso continúa, proporcionando al usuario final una búsqueda guiada en el catálogo. Por supuesto, el usuario puede retroceder, etc.

Para ayudar con esta explicación verídica (o tal vez para confundir aún más al lector ...) el siguiente fragmento proporciona una indicación más precisa de cómo se puede usar esta estructura para implementar búsquedas. Este código está adaptado para los nombres de tabla utilizados en la explicación anterior y puede incluir algunos errores tipográficos, pero en general proporcionan el sabor de las cosas. Además, esto está escrito con una Expresión de tabla común (CTE), pero bien podría escribirse como una subconsulta. Tampoco es que no nos unamos a las tablas del esquema lógico (metadatos), pero eso también podría hacerse para obtener los nombres de los atributos, el nombre del tipo y demás, directamente en el conjunto de resultados.
Como se insinuó anteriormente, las consultas y la lógica que soportan esta arquitectura son más complicadas pero también más versátiles y tolerantes a los cambios en el tipo de elementos almacenados y sus atributos. Por supuesto, este tipo de consulta se genera dinámicamente, basándose en la lista actual de criterios de búsqueda provistos por el usuario final.

WITH SearchQry AS (
    SELECT ROW_NUMBER() OVER (ORDER BY P.EntityId ASC) AS RowNum, 
     P.EntityId AS EId 
     FROM Products P 
     INNER JOIN ProductAttributes PA1 ON P.EntitityId = PA1.EntityId and PA1.AttributeID = <some attribute id, say for Manufacturer> 
     INNER JOIN ProductAttributes PA2 ON P.EntitityId = PA2.EntityId and PA2.AttributeID = <some other attribute id, say for Color> 
     -- here for additional PAn JOINs as more criteria is added 
     WHERE P.ProductType IN (ProdId_x, ProdId_y, ProdId_z) -- for example where these x,y,z Ids correspond to say "TV Sets", "LapTop Computers" and "PDAs" respectively 
      AND PA1.Value = 'SAMSUNG' -- for example 
      AND PA2.Value = 'YELLOW' -- for example 
     GROUP BY P.EntityId 
    ) 

SELECT P.EntityId, PA.AttributeId, PA.Value -- PA.IntValue (if so structured) 
FROM (SELECT * FROM SearchQry WHERE RowNum BETWEEN 1 AND 15) AS S 
JOIN ProductAttributes PA ON PA.EntityId = S.EId 
INNER JOIN Products P on P.EntityID = PA.EntityId 
ORDER BY P.EntityId, P.AttributeId -- or some other sort order 

Lo siento por la larga explicación, hay quizá [probablemente] una mejor descripción de esta línea, pero no he encontrado ...

+0

¿Me puede vincular a cualquier recurso en EAV? –

+0

Me encanta, gracias por la descripción detallada del sistema! Esto es extremadamente útil para mi proyecto. –

+0

@ Kirk: me alegro de ayudar. Ver el fragmento agregado que proporciona un "sabor" para este enfoque. Me gustaría poder encontrar alguna referencia en línea con este tipo de explicación práctica del modelo EAV, aplicado a los catálogos de la tienda; Probablemente no estoy buscando en el lugares correctos ;-) – mjv

2

En lugar de utilizar una base de datos relacional, utilice una completa autónoma - motor de búsqueda de texto para profundizaciones o búsqueda con facetas, "Solr" por ejemplo. Tarde o temprano, la "agrupación" será un problema de rendimiento cuando consulte la base de datos.

Vale la pena echar un vistazo

Solr Search Server

Cuestiones relacionadas