1

I have to sort queryset by occurrence of elements from list in two fields. Currently I wrote part that find objects:

self.filter((reduce(operator.or_, ((Q(tags__contains=tag) | Q(name__contains=string)) for tag in string.split(' ')))))

but I can't find solution to get right ordering. Ordering by occurence of elements from list, in 'tags' field Would partly solve my issue. But I prefer not to iterate over all objects in queryset..

Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
mdargacz
  • 1,267
  • 18
  • 32
  • You can't do this on Django side, except by iterating over the queryset to count the number of matching tags for each row and assign a score. You really want the db to do this work for you, if you are using PostgreSQL then this will help https://github.com/djangonauts/djorm-ext-pgfulltext – Anentropic Jun 18 '14 at 12:24

1 Answers1

2

So, you want to make objects with certain tags to display in the top?

There is similar problem. The idea is to add in select new field, which will hold boolean value, so you can sort by it.

You should add this field using django extra queryset method.

MyModel.objects.extra(
    select={
        'tags_occurance': "(tags LIKE '%tag1%') + (tags LIKE '%tag2%')"
    },
).order_by('-tags_occurance')

Should be something like this.

Community
  • 1
  • 1
dt0xff
  • 1,553
  • 1
  • 10
  • 18
  • some notes: http://pastebin.com/c0Jvd8qx where tuple([db.literal(item) for item in args]) = ["'%tag1%'", "'%tag1%'", "'%tag2%'", "'%tag2%'"] this may not be issue coused by extra({select={}) part, because when i printed query found right before place when error occurs and cut off "where" part of query it worked for me in sql console – mdargacz Jun 18 '14 at 14:02
  • Wow, this is really strange error. Try to rewrite your reduce part or make it simple. You can try to check where is the error by executing similar queries in django shell. Try to use few test tags, remove reduce part, etc. It will point you somewhere. If this error occurs even with just plain `filter(tags__contains="tag")`, it will be a reason to dig deeper. – dt0xff Jun 18 '14 at 14:34
  • Well it worked fine without extra() part, so it have to be related somehow with it.. I'll spend my today's evening on it, and let you know about reason. Anyway thanks for help, your original solution looks good, so I approve it! – mdargacz Jun 18 '14 at 15:09
  • By the way, take a look at link I provide as similar problem, maybe you will have to use a bit different query to get `tags_occurance`. – dt0xff Jun 18 '14 at 15:11