JSON中的快速搜索



我有这个JSON:

{
"statussalida": "",
"registros": [
{
"marca": 24,
"codigo": 6,
"precio": 71.9,
"precionormal": 71.9,
"descripcion": "FERNET IMPERIO",
"presentacion": "950 CC.",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "COMERCIAL ARGENTINA SRL",
"marcareal": 0,
"cantidad": 950,
"coeficiente": 1000,
"preciopor": 75.68,
"unidaddmedida": "cc",
"cantidadmayorista": 0,
"preciomayorista": 71.9,
"etiquetamedida": "Precio x 1000 cc",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjB9.0IBNNbEZXE4dKmyHxQ_oP-8HXMfEm80fI4kBCJSFaZY",
"usafoto": 0
},
{
"marca": 60,
"codigo": 888,
"precio": 274.99,
"precionormal": 274.99,
"descripcion": "ACEITE COCINERO DE OLIVA PET.",
"presentacion": "1 LT",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 1,
"coeficiente": 1,
"preciopor": 274.99,
"unidaddmedida": "Litros",
"cantidadmayorista": 0,
"preciomayorista": 274.99,
"etiquetamedida": "Precio x 1 Litro",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjB9.0IBNNbEZXE4dKmyHxQ_oP-8HXMfEm80fI4kBCJSFaZY",
"usafoto": 0
},
{
"marca": 60,
"codigo": 2368,
"precio": 82.99,
"precionormal": 82.99,
"descripcion": "ACEITE COCINERO",
"presentacion": "1,5 LT.",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 1500,
"coeficiente": 1000,
"preciopor": 55.33,
"unidaddmedida": "cc",
"cantidadmayorista": 0,
"preciomayorista": 82.99,
"etiquetamedida": "Precio x 1000 cc",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjB9.0IBNNbEZXE4dKmyHxQ_oP-8HXMfEm80fI4kBCJSFaZY",
"usafoto": 0
},
{
"marca": 60,
"codigo": 2502,
"precio": 73.49,
"precionormal": 73.49,
"descripcion": "*ACEITE COCINERO MEZCLA",
"presentacion": "1500 CC.",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 1500,
"coeficiente": 1000,
"preciopor": 48.99,
"unidaddmedida": "cc",
"cantidadmayorista": 0,
"preciomayorista": 73.49,
"etiquetamedida": "Precio x 1000 cc",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjMyNzM3fQ.HCyWPsopIAY03WZYRJ7tySUpCOE8Pq_1Ja-IFFLc0RY",
"usafoto": 0
},
{
"marca": 60,
"codigo": 6318,
"precio": 27.99,
"precionormal": 27.99,
"descripcion": "*HARINA FAVORITA 000",
"presentacion": "1KG.",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 1,
"coeficiente": 1,
"preciopor": 27.99,
"unidaddmedida": "Kg",
"cantidadmayorista": 0,
"preciomayorista": 27.99,
"etiquetamedida": "Precio x 1 Kg",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjB9.0IBNNbEZXE4dKmyHxQ_oP-8HXMfEm80fI4kBCJSFaZY",
"usafoto": 0
},
{
"marca": 60,
"codigo": 20636,
"precio": 167.9,
"precionormal": 167.9,
"descripcion": "ACEITE COCINERO",
"presentacion": "3000 CC",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 3000,
"coeficiente": 1000,
"preciopor": 55.97,
"unidaddmedida": "cc",
"cantidadmayorista": 0,
"preciomayorista": 167.9,
"etiquetamedida": "Precio x 1000 cc",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjM3MjkwfQ.ie1dLHrL3EKFYIflt0JYzI_UQzHYsmoUc_CtA2cWYd4",
"usafoto": 0
},
{
"marca": 60,
"codigo": 21821,
"precio": 136.99,
"precionormal": 136.99,
"descripcion": "*ACEITE COCINERO OLIVA EX VIRGEN",
"presentacion": "500 CC",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 500,
"coeficiente": 1000,
"preciopor": 273.98,
"unidaddmedida": "cc",
"cantidadmayorista": 0,
"preciomayorista": 136.99,
"etiquetamedida": "Precio x 1000 cc",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjM5Njc5fQ.nAMCSgGSWfcEM9D_pSFjTHQccBHrx90oSFuEl410WiM",
"usafoto": 0
},
{
"marca": 60,
"codigo": 22840,
"precio": 38.9,
"precionormal": 38.9,
"descripcion": "*ACEITE IDEAL MEZCLA",
"presentacion": "1500 CC",
"pesable": 0,
"pesableporunidad": 0,
"nombremarca": "MOLINOS RIO DE LA PLATA S.A.",
"marcareal": 0,
"cantidad": 1500,
"coeficiente": 1000,
"preciopor": 25.93,
"unidaddmedida": "cc",
"cantidadmayorista": 0,
"preciomayorista": 38.9,
"etiquetamedida": "Precio x 1000 cc",
"foto": "/api/v1/imagenes/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NDAyNzE1MDAsInBhZHJlIjoyODU3MzgyLCJpbnN0YW5jaWEiOjI2MDEyfQ.q44kAmHfbI3y_7KyuxUot-ALnYXWAxZy8QmjMg7w5gY",
"usafoto": 0
}
]
}

但这种情况在32.000篇文章中重复出现。

他们知道是否有一个函数给出了一个输入示例:'Ace'以json格式返回所有包含这些字母的文章,如何使用SQL搜索。

我试过jmespath、jsonpath ng、ijson等等,但我做不到我需要的。

问题是,当他们想搜索文章时,我为什么要从api中使用json,而我必须返回到电子商务中,而且应该尽可能快。

json = requests.get('http://xxx.xxx.x.xx/api/v1/articulosweb')
a = jmespath.search("descripcion == 'Fer'", json.content)

在这里,我希望您返回所有在描述中包含'fer'的文章。

这看起来像是jq(json查询(的作业,它有一个独立的包https://stedolan.github.io/jq/和Python绑定https://pypi.org/project/jq/

使用纯python也不难做到这一点。以下代码给出了两者的示例:

import jq
import json

# Grab the text of the json
with open('test.json', 'r') as file:
json_text = file.read()
# Create a JQ query
query = jq.compile('.registros[] | select(.descripcion | ascii_downcase | test(".*fer.*"))')
# Execute the JQ Query (does not require a json.loads call)
found = query.input(text=json_text).all()

# Or, use json.loads and just use basic python
data = json.loads(json_text)
found2 = []
for item in data['registros']:
if 'fer' in item['descripcion'].lower():
found2.append(item)

assert found == found2

编辑:

尽管JQ是一个编译过的二进制文件,但Pure-python可能只是更快。我将数据的大小乘以10000,并使用timerit进行了基准测试。纯python解决方案似乎要快得多,当将循环更改为列表理解时,速度甚至更快。

import copy
data_big = copy.deepcopy(data)
data_big['registros'] = [item for _ in range(10000) for item in data['registros']]
json_text_big = json.dumps(data_big)

import timerit
ti = timerit.Timerit(3, bestof=1, verbose=2)
for timer in ti.reset('pure-python'):
with timer:
found3 = []
data_big = json.loads(json_text_big)
for item in data_big['registros']:
if 'fer' in item['descripcion'].lower():
found3.append(item)
for timer in ti.reset('pure-python-list-comprehension'):
with timer:
data_big = json.loads(json_text_big)
found5 = [item for item in data_big['registros'] if 'fer' in item['descripcion'].lower()]

for timer in ti.reset('with jq'):
with timer:
found4 = query.input(text=json_text_big).all()
assert found4 == found3

结果:

Timed pure-python for: 3 loops, best of 1
time per loop: best=273.871 ms, mean=327.134 ± 47.9 ms
Timed pure-python-list-comprehension for: 3 loops, best of 1
time per loop: best=10.701 ms, mean=18.303 ± 10.0 ms
Timed with jq for: 3 loops, best of 1
time per loop: best=5.298 s, mean=5.600 ± 0.2 s

相关内容

  • 没有找到相关文章

最新更新