我正在尝试在几个字段上进行搜索,其中一些字段可以留空。 给出MongoDB中的以下Json文档(这里只有三个字段,但实际上是N个字段,N> 10):
{
'first_name' : 'value_X',
'last_name' : 'value_Y',
'mail_adress' : 'value_Z'
}
然后让我们假设一个表单,用户可以在其中输入名字,姓氏,邮件地址和电话号码的值。 如果填充了所有字段,则MongoDB中的查询如下所示:
db.collection.find( {
'first_name' : 'value_A',
'last_name' : 'value_B',
'mail_adress' : 'value_C'
}
)
我遇到的问题是用户可能会将某些字段留空: 这意味着我的查询也可以变为:
db.collection.find({ 'first_name' : 'value_A' })
或
db.collection.find( {'last_name' : 'value_B'})
或
db.collection.find( {'mail_adress' : 'value_C'})
或
db.collection.find( {'first_name' : 'value_A','last_name' : 'value_B'})
或
db.collection.find( {'first_name' : 'value_A','last_name' : 'value_C'})
或
db.collection.find( {'last_name' : 'value_B','mail_adress' : 'value_C'})
我想知道是否需要为每个特定实例编写查询? 我还想过根据用户输入的字段动态生成查询,因为查询是Json doucment会很容易。
我也想知道MongoDB是否可以忽略字段,如果它们为空(但我不想在我的查询中失去性能)
任何人都可以帮助我吗?感谢
编辑于20140404下午6点:部分答案
这是带有Aditya建议的Python代码。 我还添加了关于在前端生成查询的python代码,如svjn建议:
'''
Created on 4 Apr 2014
@author: scoulombel
'''
import pymongo
from pymongo import MongoClient
import random
import string
# fill the database
def fillCollection(collection):
doc = {
'first_name' : 'value_X',
'last_name' : 'value_Y',
'mail_adress' : 'value_Z'
}
docID = collection.insert(doc)
for _ in range(0,10):
doc = {
'first_name' : ''.join(random.choice(string.ascii_uppercase) for _ in range(4)) + ''.join(random.choice(string.digits) for _ in range(4)),
'last_name' : ''.join(random.choice(string.ascii_uppercase) for _ in range(4)) + ''.join(random.choice(string.digits) for _ in range(4)),
'mail_adress' : ''.join(random.choice(string.ascii_uppercase) for _ in range(4)) + ''.join(random.choice(string.digits) for _ in range(4))
}
docID = collection.insert(doc)
# read data in a cursor
def readCursor(cursor):
object_list = []
count = 0
for doc in cursor :
del doc["_id"]
count += 1
doc['resOrder'] = count
object_list.append(doc)
print object_list
if __name__ == '__main__':
#client = MongoClient()
client = MongoClient('ip', 'port')
db = client.test_OR_AND_DB
collection = db.collection
fillCollection(collection)
# SEARCH VALUE which can be null or not
value_A = 'value_X'
value_B = 'null' #'value_Y'
value_C = 'null' #'value_Z'
# APPROACH 1 : ADITYA answer for search
cursor1 = db.collection.find(
{
'$or' : [
{ '$and' : [ {'first_name' : { '$ne': 'null' }}, {'first_name' : value_A } ]},
{ '$and' : [ {'last_name' : { '$ne': 'null' }}, {'last_name' : value_B } ]},
{ '$and' : [ {'mail_adress' :{ '$ne' :'null' }}, {'mail_adress':value_C } ]}
]
}
)
readCursor(cursor1)
# APPROACH 2 ; create a JSON representing the query dynamically
path_value_dict = {'first_name':value_A, 'last_name':value_B, 'mail_address':value_C} # if embedded it would be for instance name.first_name
query= {}
for key in path_value_dict.keys():
if path_value_dict[key] != 'null':
query[key] = path_value_dict[key]
print query
cursor2 = db.collection.find({'first_name': 'value_X', 'mail_adress': 'value_Z'})
readCursor(cursor2)
答案 0 :(得分:0)
使用Mongodb $or运算符进行查询。
$或运算符对两个或更多<expressions>
的数组执行逻辑OR运算,并选择满足至少一个<expressions>
的文档。
db.collection.find({
$or : [{ $and : [ {'first_name' : { $ne:null }, {'first_name' :'value_A' }]},
{ $and : [ {'last_name' : { $ne:null }, {'last_name' :'value_B' }]},
{ $and : [ {'mail_addres' :{ $ne:null }, {'mail_addres':'value_C'}]}
]}
);