Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

import re 

import json 

 

def _decode_pattern_list(data): 

    rv = [] 

    for item in data: 

        if isinstance(item, unicode): 

            item = item.encode('utf-8') 

        elif isinstance(item, list): 

            item = _decode_pattern_list(item) 

        elif isinstance(item, dict): 

            item = _decode_pattern_dict(item) 

        rv.append(item) 

 

        rv = sorted(rv) 

    return rv 

 

def _decode_pattern_dict(data): 

    rv = {} 

    for key, value in data.iteritems(): 

        if isinstance(key, unicode): 

            key = key.encode('utf-8') 

            if key in ['$in', '$gt', '$gte', '$lt', '$lte', '$exists']: 

                return 1 

            if key == '$nin': 

                value = 1 

            if key in ['query', '$query']: 

                return _decode_pattern_dict(value) 

 

        if isinstance(value, list): 

            value = _decode_pattern_list(value) 

        elif isinstance(value, dict): 

            value = _decode_pattern_dict(value) 

        else: 

            value = 1 

 

        rv[key] = value 

    return rv 

 

 

def json2pattern(s): 

    """ converts JSON format (even mongo shell notation without quoted key names) to a query pattern """ 

    # make valid JSON by wrapping field names in quotes 

    s, _ = re.subn(r'([{,])\s*([^,{\s\'"]+)\s*:', ' \\1 "\\2" : ' , s) 

    # convert values to 1 where possible, to get rid of things like new Date(...) 

    s, n = re.subn(r'([:,\[])\s*([^{}\[\]"]+?)\s*([,}\]])', '\\1 1 \\3', s) 

 

    # now convert to dictionary, converting unicode to ascii  

    try: 

        doc = json.loads(s, object_hook=_decode_pattern_dict) 

        return json.dumps(doc, sort_keys=True, separators=(', ', ': ') ) 

    except ValueError: 

        return None 

 

 

if __name__ == '__main__': 

 

    s = '{d: {$gt: 2, $lt: 4}, b: {$gte: 3}, c: {$nin: [1, "foo", "bar"]}, "$or": [{a:1}, {b:1}] }' 

    print json2pattern(s) 

 

    s = '{a: {$gt: 2, $lt: 4}, "b": {$nin: [1, 2, 3]}, "$or": [{a:1}, {b:1}] }' 

    print json2pattern(s) 

 

    s = '{ a: 1, b: { c: 2, d: "text" }, e: "more test" }' 

    print json2pattern(s) 

 

    s = '{ _id: ObjectId(\'528556616dde23324f233168\'), config: { _id: 2, host: "localhost:27017" }, ns: "local.oplog.rs" }' 

    print json2pattern(s)