Как получить элементы по полю массива и отфильтровать поле массива, чтобы вернуть только совпадающие элементы? - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть словарь, содержащий тысячи таких элементов:

{
'_id': ObjectId('5e9cd87f8b5ab6d445edab5f'), 
'id': 'XXX-YYY-ZZZ', 
'Published': datetime.datetime(2020, 2, 25, 18, 15), 
'summary': 'Some information', 
'subelements': [
    "Apple", "Car", "Glass"     // Thousands more
]
}

Поле 'subelements' может содержать тысячи строк.

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

Например, при поиске «Apple» должно возвращаться:

{
'_id': ObjectId('5e9cd87f8b5ab6d445edab5f'), 
'id': 'XXX-YYY-ZZZ', 
'Published': datetime.datetime(2020, 2, 25, 18, 15), 
'summary': 'Some information', 
'subelements': [
    "Apple"
]
}
// other matches ...

и поиск «Яблоко», «Автомобиль» и т. Е. «Книга» должны вернуть:

{
'_id': ObjectId('5e9cd87f8b5ab6d445edab5f'), 
'id': 'XXX-YYY-ZZZ', 
'Published': datetime.datetime(2020, 2, 25, 18, 15), 
'summary': 'Some information', 
'subelements': [
    "Apple", "Car"
]
}
// other matches

Правка - некоторые актуальные элементы из моего дела. Я работаю с базой данных CVE и хочу использовать один запрос, чтобы найти CVE для нескольких CPE:

{
    "id": "CVE-1999-0001",
    "assigner": "cve@mitre.org",
    "Published": {
        "$date": {
            "$numberLong": "946530000000"
        }
    },
    "Modified": {
        "$date": {
            "$numberLong": "1292475600000"
        }
    },
    "summary": "ip_input.c in BSD-derived TCP/IP implementations allows remote attackers to cause a denial of service (crash or hang) via crafted packets.",
    "access": {
        "authentication": "NONE",
        "complexity": "LOW",
        "vector": "NETWORK"
    },
    "impact": {
        "availability": "PARTIAL",
        "confidentiality": "NONE",
        "integrity": "NONE"
    },
    "cvss": {
        "$numberDouble": "5"
    },
    "cvss-time": {
        "$date": {
            "$numberLong": "1292475600000"
        }
    },
    "cvss-vector": "AV:N/AC:L/Au:N/C:N/I:N/A:P",
    "references": ["http://www.openbsd.org/errata23.html#tcpfix", "http://www.osvdb.org/5707"],
    "vulnerable_configuration": ["cpe:2.3:o:bsdi:bsd_os:3.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.0:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.1.5.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.2:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.0:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.0.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.0.5:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.5:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.6:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.6.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.7:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.7.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.2:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.3:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.4:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.5:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.6:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.8:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:3.0:*:*:*:*:*:*:*", "cpe:2.3:o:openbsd:openbsd:2.3:*:*:*:*:*:*:*", "cpe:2.3:o:openbsd:openbsd:2.4:*:*:*:*:*:*:*"],
    "vulnerable_product": ["cpe:2.3:o:bsdi:bsd_os:3.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.0:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.1.5.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:1.2:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.0:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.0.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.0.5:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.5:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.6:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.6.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.7:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.1.7.1:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.2:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.3:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.4:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.5:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.6:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:2.2.8:*:*:*:*:*:*:*", "cpe:2.3:o:freebsd:freebsd:3.0:*:*:*:*:*:*:*", "cpe:2.3:o:openbsd:openbsd:2.3:*:*:*:*:*:*:*", "cpe:2.3:o:openbsd:openbsd:2.4:*:*:*:*:*:*:*"],
    "cwe": "CWE-20",
    "vulnerable_configuration_cpe_2_2": []
}

1 Ответ

0 голосов
/ 24 апреля 2020

Вы можете сравнить затем как наборы, т.е. набор comapre с набором вместо проверки каждого элемента в списке

import pandas as pd
import datetime

data = [{
# '_id': str(ObjectId('5e9cd87f8b5ab6d445edab5f')), 
'id': 'XXX-YYY-ZZZ', 
'Published': datetime.datetime(2020, 2, 25, 18, 15), 
'summary': 'Some information', 
'subelements': [
    "Apple", "Car"
]
},
{
# '_id': str(ObjectId('5e9cd87f8b5ab6d445edab5f')), 
'id': 'XXX-YYY-ZZZ', 
'Published': datetime.datetime(2020, 2, 25, 18, 15), 
'summary': 'Some information', 
'subelements': [
    "Apple", "Car","Onion"
]
},
{
# '_id': str(ObjectId('5e9cd87f8b5ab6d445edab5f')), 
'id': 'XXX-YYY-ZZZ', 
'Published': datetime.datetime(2020, 2, 25, 18, 15), 
'summary': 'Some information', 
'subelements': [
    "Apple", "Car","Watch"
]
}
]

df = pd.DataFrame(data)

def toSet (inp):
    return set(inp)
df['set'] = df.apply(lambda x: toSet(x.subelements), axis=1)
print(df[df ['set'] == set(['Car','Apple'])])
            id           Published  ...   subelements           set
0  XXX-YYY-ZZZ 2020-02-25 18:15:00  ...  [Apple, Car]  {Car, Apple}

...