Форум сайта python.su
Небольшой пример на основании приведенной таблицы элементов для того, чтобы убедиться - мы имеем в виду одно и то же.
1. Выводим первые Х тегов.
2. Выбираем тэг В — в выборке остаются элементы 1, 2, 4, 10. В облаке остаются тэги А, В, С, D, F. Что еще нужно вывести, количество каждого тэга в полученном списке элементов: А = 1, B = 4, C = 2, D = 1, F = 1, так? Еще что-то?
3. Выбираем второй тэг C — в выборке 2 элемента: 1 и 2. В облаке остаются тэги: A, B, C, D. Аналогично п.2 А = 1, B = 2, C = 2, D = 1. Дополнительно выводим то, что было задумано в п.2.
4. Выбираем третий тэг А — в выборке элемент 1. В облаке: A, B, C. Все тэги имеют значение 1.
Так?
Если еще что-то нужно выводить, покажи на этом примере что выводится и какое значение должно иметь, исходя из приведенных данных.
Офлайн
o7412369815963Да, согласен. Без списка id объектов, оттеженых каждым тэгом не получить.
это и есть простой граф который я выложил выше в посте 35, из него не получить фильтр по 2-м тегам
Офлайн
мдя, map_reduce можно же на find накладывать… тогда должно быстрее гораздо работать, ща проверю :)
Lexanderда, так… надо будет проверить производительность :)
Так?
Если еще что-то нужно выводить, покажи на этом примере что выводится и какое значение должно иметь, исходя из приведенных данных.
Офлайн
Edидея не плохая, но тегов 5К.
Ну и так далее. Все находится простым пересечением множеств. Того же redis-а тут должно хватить за глаза. Или проблема в том, что хранить оба соответствия объект - тэг и тэг - объект не хочется?
Офлайн
o7412369815963сделал так:
мдя, map_reduce можно же на find накладывать… тогда должно быстрее гораздо работать, ща проверю :)
tags = db.events.map_reduce(map, reduce, query={ 'tags': { '$all': [ 'a', 'b' ] } })
tags = list(tags.find().sort('value',DESCENDING).limit(100))
Офлайн
То, что тэгов 5K еще полбеды. Оттеженых одним тэгом объектов может быть потенциально 1M, а это хуже.
Но redis такое вроде как умеет. Вот из его FAQ:
Q: What is the maximum number of keys a single Redis instance can hold? and what the max number of elements in a List, Set, Ordered Set?¶
A: In theory Redis can handle up to 2^32 keys, and was tested in practice to handle at least 150 million of keys per instance. We are working in order to experiment with larger values.
Every list, set, and ordered set, can hold 2^32 elements.
Actually Redis internals are ready to allow up to 2^64 elements but the current disk dump format don't support this, and there is a lot time to fix this issues in the future as currently even with 128 GB of RAM it's impossible to reach 2^32 elements.
Отредактировано (Сен. 18, 2010 22:12:00)
Офлайн
получен более менее неплохой результат, редис пока отложу.
o7412369815963итого: объектов 200К, тегов 500, на каждый объект по 5 тегов
ща сделаю разнообразие тегов поболее, т.е. приближу к реальности, должно ещё шустрее обрабатываться
Офлайн
o7412369815963результат:
сейчас протестирую на 1М объектов, 5К тегов, 10 тегов на элемент
Отредактировано (Сен. 18, 2010 23:14:08)
Офлайн
Выложи плиз решение, интересно очень )
Офлайн
это добавление тегов в граф (старый список тегов и новый для одного объекта)
def EventTags_set(t_old1,t_new1):
#r = []
#for t in t_old:
# if t in t_new: r.append(t)
#for t in r:
# del t_old[t]
# del t_new[t]
#raise Exception(str( t_new ))
t_old = []
for t in t_old1:
if t not in t_new1: t_old.append(t)
t_new = []
for t in t_new1:
if t not in t_old1: t_new.append(t)
# remove
db = getDBn()
for name in t_old:
tag = db.events_tags.find_one({ 'name':name })
if not tag: continue
tag['count'] -= 1
tags = tag['tags']
for n in t_old:
if name != n:
if n in tags:
if tags[n] < 2: del tags[n]
else: tags[n] -= 1
db.events_tags.save(tag)
# append
for name in t_new:
tag = db.events_tags.find_one({ 'name':name })
if not tag: tag = { 'name':name, 'tags':{}, 'count':0 }
tag['count'] += 1
tags = tag['tags']
for n in t_new:
if name != n:
if n in tags: tags[n] += 1
else: tags[n] = 1
db.events_tags.save(tag)
def EvenetTags_list(tags):
db = getDBn()
if not len(tags): return db.events_tags.find({},{ 'name':1, 'count':1 }).sort('count',DESCENDING)
elif len(tags) == 1:
tt = db.events_tags.find_one({ 'name':tags[0] })
if not tt: return []
tt = tt['tags']
return sorted( [ { 'name':t, 'count':tt[t]} for t in tt ] , key=lambda x:x['count'], reverse=True )
map = Code(""" function() {
this.tags.forEach(
function(x) {
emit(x, 1);
}
);
}""")
reduce = Code("""function (key, values) {
var total = 0;
for(var i in values) total += values[i];
return total;
}""")
result = db.events.map_reduce(map, reduce, query={ 'tags': { '$all': tags } })
result = list(result.find().sort('value',DESCENDING).limit(100))
return [ { 'name':x['_id'], 'count':x['value'] } for x in result if x['_id'] not in tags ]
Отредактировано (Сен. 21, 2010 05:33:30)
Офлайн