0

If I have an Algolia index containing documents that look like these:

{"object_id":1, "color":"red", "shape":"circle"}
{"object_id":2, "color":"blue", "shape":"triangle"}
{"object_id":3, "color":"green", "shape":"square"}
{"object_id":4, "color":null, "shape":"hexagon"}
{"object_id":5, "shape":"hexagon"}
...

Using the python API for Algolia, how can I search the index to get objects like 4 and 5 back since they are both missing the "color" attribute.

I've been dragging through (https://www.algolia.com/doc/api-client/python/search#search-in-an-index) but I cannot find the answer.

I've tried this snippet but no luck:

from algoliasearch import algoliasearch

client = algoliasearch.Client("YourApplicationID", 'YourAPIKey')
index = client.init_index("colorful_shapes")
res = index.search("null")
res1 = index.search("color=null")
res2 = index.search("color:null")
res3 = index.search("!color")
print(res, res1, res2, res3)
ldz
  • 2,217
  • 16
  • 21

2 Answers2

1

Unfortunately, searching for all objects with a missing key is not possible in Algolia (and btw pretty complex for schema-less NoSQL engines).

A simple work-around is to push - at indexing time - a tag inside to specify if the attribute is set or not:

{
  "objectID": 1,
  "myattr": "I'm set",
  "_tags": ["myattr_set"]
}

and

{
  "objectID": 2,
  "_tags": ["myattr_unset"]
}

At query time, you would filter the searches with the tag:

index.search('your query', { filters: 'myattr_unset', ... })
redox
  • 2,269
  • 13
  • 22
0

I'm sure there are more elegant solutions, but this seems to work for what you provided (also I assumed your null was an intended None):

a = [{"object_id":1, "color":"red", "shape":"circle"}, {"object_id":2, "color":"blue", "shape":"triangle"}, {"object_id":3, "color":"green", "shape":"square"}, {"object_id":4, "color":None, "shape":"hexagon"}, {"object_id":5, "shape":"hexagon"}]
list(a) #since dict has no set order
for i in a:
    try:
        if (i['color'] is None):
            print(a.index(i)) #prints 3
    except KeyError:
        print(a.index(i)) #prints 4

I know you expect 4 and 5 printed, but indexes start counting at 0, this can easily be changed just by adding 1 to each print statement.

Rafael
  • 3,096
  • 1
  • 23
  • 61
  • sorry I just realized how generic my question was worded beforehand. I have edited it to be more specific to using Algolia. Your solution is definitely usable if I grab all the objects from the index, but I am trying to avoid that scenario and have the technology do that work for me. – user2109431820398 Nov 15 '16 at 05:39