Запросы для обновления и удаления данных

Запросы для обновления (UPDATE) и удаления (DELETE) применяются в Reindexer для выполнения следующих операций:

  • изменение содержимого полей записи или группы записей,
  • добавление новых полей,
  • удаление неиндексных полей,
  • удаление записей.

UPDATE-запросы для изменения и добавления полей записей

В Reindexer используется следующий синтаксис запросов на обновление данных:

db.Query("nsName")
    .Where("field", reindexer.EQ, 40)
    .Set("field1", value1)
    .Set("field2", value2)
    ...
    .Set("fieldN", valueN)
    .Update()

Кроме того, в одном запросе можно объединить несколько выражений Set... разных типов, например: Set(...).SetExpression(...).SetObject(...)...

(
    db.new_query("nsName")
        .where("field", CondType.CondEq, 40)
        .set("field1", [value1])
        .set("field2", [value2])
        ...
        .set("fieldN", [valueN])
        .update()
)
db.query("items", Item.class)
    .where("field", Condition.EQ, 40)
    .set("field1", value1)
    .set("field2", value2)
    // ...
    .set("fieldN", valueN)
    .update();
UPDATE nsName
SET field1 = value1, field2 = value2, ..
WHERE condition;
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        2
      ]
    }
  ],
  "update_fields": [
    {
      "name": "info",
      "type": "value",
      "is_array": false,
      "values": [
        "new info"
      ]
    }
  ]
}'

Изменение типа значения поля при обновлении записи

В Reindexer механизмы обновления полей имеют следующие особенности:

  • При изменении неиндексного поля замена текущего значения на значение другого типа полностью заменяет содержимое поля, устанавливается значение другого типа.

    Пример:

    Записываем в поле значение типа int:

    UPDATE nsName SET newField = 3 WHERE id = 5
    

    Обновляем поле, записываем в него значение типа string:

    UPDATE nsName SET newField = 'String' WHERE id = 5
    

    Запрос выполнится успешно.

  • Значения индексных полей можно преобразовать только в смежный типы. Например, int в числовую строку вида ‘123456’ и обратно, либо bool  в строку вида ’true’ и обратно.

    Пример:

    Обновляем индексное поле с типом значения int, записываем в него числовую строку:

    UPDATE nsName SET newField = '123' WHERE id = 5
    

    Запрос выполнится успешно.

    Обновляем индексное поле с типом значения int, записываем в него строку:

    UPDATE nsName SET newField = 'Text' WHERE id = 5
    

    Получим ошибку “Can`t convert Text to number”.

  • Изменение значения индексного поля-массива на null возвращает его к значению по умолчанию.

Добавление новых полей к записям в неймспейсах

С помощью UPDATE-запросов возможно добавление новых полей к существующим записям в неймспейсе. Можно добавить поле для одной или нескольких записей.

Пример:

db.Query("items")
    .Where("id", reindexer.GE, 100)
    .Set("newField", "Brand new!")
    .Update()
(
    db.new_query("items")
        .where("id", CondType.CondGe, 100)
        .set("newField", ["Brand new!"])
        .update()
)
db.query("items", Item.class)
    .where("id", Condition.GE, 100)
    .set("newField", "Brand new!")
    .update();
UPDATE items SET newField = 'Brand new!' WHERE id > 100
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "GE",
      "Value": [
        100
      ]
    }
  ],
  "update_fields": [
    {
      "name": "newField",
      "type": "value",
      "is_array": false,
      "values": [
        "Brand new!"
      ]
    }
  ]
}'

Добавление вложенных полей с несколькими уровнями вложенности

В Reindexer возможно добавление вложенных полей с несколькими уровнями вложенности.

Код из примеров добавляет в неймспейс items поле nested с вложенными объектами nested2, nested3, nested4. В nested4 добавляется поле newField с содержимым new nested field!:

db.Query("items")
    .Where("id", reindexer.GE, 100)
    .Set("nested.nested2.nested3.nested4.newField", "new nested field!")
    .Update()
(
    db.new_query("items")
        .where("id", CondType.CondGe, 100)
        .set("nested.nested2.nested3.nested4.newField", ["new nested field!"])
        .update()
)
db.query("items", Item.class)
    .where("id", Condition.GE, 100)
    .set("nested.nested2.nested3.nested4.newField", "new nested field!")
    .update();
UPDATE items SET nested.nested2.nested3.nested4.newField = 'new nested field!' WHERE id > 100

Для добавления вложенных полей при обновлении записей по HTTP значение поля “update_fields” -> “type” в теле запроса должно быть object.

curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "GE",
      "Value": [
        100
      ]
    }
  ],
  "update_fields": [
    {
      "name": "nested",
      "type": "object",
      "is_array": false,
      "values": [
        {
          "nested2": {
            "nested3": {
              "nested4": {
                "newField": "new nested field!"
              }
            }
          }
        }
      ]
    }
  ]
}'

Арифметические выражения в UPDATE-запросах

При выполнении UPDATE-запросов к Reindexer возможно добавление в них арифметических выражений с использованием следующих знаков:

  • + (сложение),
  • - (вычитание),
  • / (деление),
  • * (умножение),
  • ().

Пример запроса на обновление данных в Reindexer с использованием арифметических выражений:

При взаимодействии с Reindexer через Go-коннектор для добавления в запрос арифметических выражений используйте метод SetExpression().

db.Query("items")
    .Where("field5", reindexer.EQ, 1)
    .SetExpression("field", "field1+field2")
    .Update()
(
    db.new_query("items")
        .where("field5", CondType.CondEq, 1)
        .expression("field", "field1+field2")
        .update()
)
UPDATE items SET field1 = field2+field3-(field4+5)/2 WHERE field5 = 1

Для добавления арифметических выражений при обновлении поля по HTTP значение поля “update_fields” -> “type” в теле запроса должно быть expression.

curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "field",
      "type": "expression",
      "is_array": false,
      "values": [
        "field1 + field2"
      ]
    }
  ]
}'

Также в UPDATE-запросах можно использовать такие функции, как now(), sec(), serial().

Пример:

При взаимодействии с Reindexer через Go-коннектор для добавления в запрос арифметических выражений и функций используйте метод SetExpression().

db.Query("items").Where("id", reindexer.EQ, 3).SetExpression("field", "field2*now()").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 3)
        .expression("field", "field2*now()")
        .update()
)
UPDATE items SET field1 = field2*NOW() WHERE id = 3

Для добавления арифметических выражений при обновлении поля по HTTP значение поля “update_fields” -> “type” в теле запроса должно быть expression.

curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "field",
      "type": "expression",
      "is_array": false,
      "values": [
        "field1 * now()"
      ]
    }
  ]
}'

Обновление полей-массивов

В Reindexer реализован механизм обновления, который позволяет изменять определенный элемент существующего массива или заменять поле-массив целиком.

Примеры:

Изменение элемента массива:

db.Query("items").Where("id", reindexer.EQ, 11).Set("arrayField[0]", 3).Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 11)
        .set("arrayField[0]", [3])
        .update()
)
db.query("items", Item.class)
    .where("id", Condition.EQ, 11)
    .set("arrayField[0]", 3)
    .update();
UPDATE items SET arrayField[0] = 3 WHERE id = 1

Для изменения элемента массива по HTTP значение поля “update_fields” -> “type” в теле запроса должно быть value.

curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        11
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField[0]",
      "type": "value",
      "is_array": false,
      "values": [
        3
      ]
    }
  ]
}'

Обновление всего массива:

db.Query("items").Where("id", reindexer.EQ, 11).Set("arrayField", []int{999, 1999, 2999}).Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 11)
        .set("arrayField", [999, 1999, 2999])
        .update()
)
db.query("items", Item.class)
    .where("id", Condition.EQ, 11)
    .set("arrayField", List.of(999, 1999, 2999))
    .update();
UPDATE items SET arrayField = [999, 1999, 2999] WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        11
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "value",
      "is_array": true,
      "values": [
        999,
        1999,
        2999
      ]
    }
  ]
}'

Добавление элементов в начало массива:

Для добавления элементов в начало массива через Go используйте метод SetExpression().

db.Query("items").Where("id", reindexer.EQ, 11).SetExpression("arrayField", "[999, 1999, 2999] || arrayField").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 11)
        .expression("arrayField", "[999, 1999, 2999] || arrayField")
        .update()
)
UPDATE items SET arrayField = [999, 1999, 2999] || arrayField WHERE id = 1

Для добавления элементов в начало массива по HTTP значение поля “update_fields” -> “type” в теле запроса должно быть expression.

curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        11
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "[999, 1999, 2999]||arrayField"
      ]
    }
  ]
}'

Добавление элементов в конец массива:

Для добавления элементов в конец массива через Go используйте метод SetExpression().

db.Query("items").Where("id", reindexer.EQ, 11).SetExpression("arrayField", "arrayField || [999, 1999, 2999]").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 11)
        .expression("arrayField", "arrayField || [999, 1999, 2999]")
        .update()
)
UPDATE items SET arrayField = arrayField || [999, 1999, 2999] WHERE id = 1

Для добавления элементов в конец массива по HTTP значение поля “update_fields” -> “type” в теле запроса должно быть expression.

curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        11
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "arrayField||[999, 1999, 2999]"
      ]
    }
  ]
}'

Обновление массивов объектов

Reindexer также позволяет обновлять элементы массивов объектов.

Примеры:

Обновление элемента массива объектов:

Для обновления элемента массива объектов через Go используйте метод SetObject().

db.Query("items").Where("id", reindexer.EQ, 1).SetObject("objectsArray[0]", &Item{id: 0, Description: "Updated!"}).Update()

Для обновления элемента массива объектов через Python используйте метод set_object().

(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .set_object("objectsArray[0]", [{"id": 0, "Description": "Updated!"}])
        .update()
)
UPDATE items SET objectsArray[0] = {"Id":0,"Description":"Updated!"} WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "objectsArray[0]",
      "type": "object",
      "is_array": false,
      "values": [
        {
          "Id": 0,
          "Description": "Updated"
        }
      ]
    }
  ]
}'

Обновление индексного Array-поля, находящегося внутри массива объектов:

Пример ниже рассмотрен для неймспейса с именем ns, в котором есть индекс с параметрами: name="nested",json_paths=["nested.field1"] и is_array=true.

ВАЖНО. Для фильтрации (выборки массива объектов) при выполнении таких запросов используйте имя индекса (в примере — nested). А для изменения значений вложенных полей — их jsonpath (в примере — nested[1].field1).

Исходная запись:

{
    "id":1,
    "nested":[{"field1": 1, "field2": 2},
              {"field1": 3, "field2": 4},
              {"field1": 5, "field2": 6}]
}

Запись после обновления индексного Array-поля, находящегося внутри массива объектов:

{
    "id":1,
    "nested":[{"field1": 1, "field2": 2},
              {"field1": 123, "field2": 4},
              {"field1": 5, "field2": 6}]
}

Для обновления индексного Array-поля, находящееся внутри массива объектов, через Go используйте метод Set().

db.Query("test").Where("nested", reindexer.EQ, 1).Set("nested[1].field1", 123).Update()
(
    db.new_query("test")
        .where("nested", CondType.CondEq, 1)
        .set("nested[1].field1", [123])
        .update()
)
db.query("items", Item.class)
    .where("nested", Condition.EQ, 1)
    .set("nested[1].field1", 123)
    .update();
UPDATE ns SET nested[1].field1 = 123 WHERE nested = 1
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "ns",
  "filters": [
    {
      "Field": "nested",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "nested[1].field1",
      "values": [
        123
      ]
    }
  ]
}'

Обновление индексного поля, находящегося внутри массива объектов, с заменой типа поля (массив -> скаляр и наоборот):

Reindexer позволяет обновлять индексные поля, находящееся внутри массива объектов, и одновременно с этим менять их тип.

Такое обновление доступно только для смены типа поля со скалярного на массив и наоборот.

Пример ниже рассмотрен для неймспейса с именем ns, в котором есть индекс с параметрами: name="nested_field",json_paths=["nested.field1"] и is_array=true.

Исходная запись:

{
    "id":1,
    "nested":[{"field1": [1,2]},{"field1": 3 }] // Тип поля "field1" — массив
}

Запись после обновления и изменения типа индексного поля, находящегося внутри массива объектов, с массива на скалярный:

{
    "id":1,
    "nested":[{"field1": 123},{"field1": 3 }] // Тип поля "field1" — изменен на скалярный
}

Для обновления индексного Array-поля, находящееся внутри массива объектов, через Go используйте метод Set().

db.Query("test").Where("nested_field", reindexer.EQ, 1).Set("nested[0].field1", 123).Update()
(
    db.new_query("test")
        .where("nested_field", CondType.CondEq, 1)
        .set("nested[0].field1", [123])
        .update()
)
db.query("test", Item.class)
    .where("nested_field", Condition.EQ, 1)
    .set("nested[0].field1", 123)
    .update();
UPDATE ns SET nested[0].field1 = 123 WHERE nested_field = 1
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "ns",
  "filters": [
    {
      "Field": "nested_field",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "nested[0].field1",
      "values": [
        123
      ]
    }
  ]
}'

Изменение и добавление полей объектов

Reindexer позволяет обновлять и добавлять поля объектов.

Примеры:

Объект может быть задан как struct, map или в виде байтового массива (то есть JSON-версии представления объекта).

type ClientData struct {
  Name          string `reindex:"name" json:"name"`
  Age           int    `reindex:"age" json:"age"`
  Address       string `reindex:"address" json:"address"`
  Occupation    string `reindex:"occupation" json:"occupation"`
  TaxYear       int    `reindex:tax_year json:"tax_year"`
  TaxConsultant string `reindex:tax_consultant json:"tax_consultant"`
}

type Client struct {
  ID      int         `reindex:"id" json:"id"`
  Data    ClientData  `reindex:"client_data" json:"client_data"`
}

clientData := []interface{}{
    map[string]string{"name": "Jane Doe"},
    map[string]int{"age": 25},
    map[string]string{"address": "23 Main St, LA"},
    map[string]string{"occupation": "Accountant"},
    map[string]int{"tax_year": 2025},
    map[string]string{"tax_consultant": "Sean O'Something"}
}

db.Query("clients").Where("id", reindexer.EQ, 100).SetObject("client_data", clientData).Update()

При передаче объекта в SetObject в виде map требуется использовать map с ключами типа string (например, map[string]interface{}).

client = [
    {
        "name": "id",
        "json_paths": ["id"],
        "field_type": "int",
        "is_pk": True
    },
    {
        "name": "client_data.name",
        "json_paths": ["client_data.name"],
        "field_type": "string"
    },
    {
        "name": "client_data.age",
        "json_paths": ["client_data.age"],
        "field_type": "int"
    },
    {
        "name": "client_data.address",
        "json_paths": ["client_data.address"],
        "field_type": "string"
    },
    {
        "name": "client_data.occupation",
        "json_paths": ["client_data.occupation"],
        "field_type": "string"
    },
    {
        "name": "client_data.tax_year",
        "json_paths": ["client_data.tax_year"],
        "field_type": "int"
    },
    {
        "name": "client_data.tax_consultant",
        "json_paths": ["client_data.tax_consultant"],
        "field_type": "string"
    }
]

client_data = {
    "name": "Jane Doe",
    "age": 25,
    "address": "23 Main St, LA",
    "occupation": "Accountant",
    "tax_year": 2025,
    "tax_consultant": "Sean O'Something"
}

(
    db.new_query("clients")
        .where("id", CondType.CondEq, 1)
        .set_object("client_data", [client_data])
        .update()
)
public static class ClientData {

    @Reindex(name = "name")
    private String name;

    @Reindex(name = "age")
    private int age;

    @Reindex(name = "year")
    private int year;

    @Reindex(name = "occupation")
    private String occupation;

    @Reindex(name = "tax_year")
    private int taxYear;

    @Reindex(name = "tax_consultant")
    private String taxConsultant;

    public ClientData() {
    }

    public ClientData(String name, int age, int year, String occupation, int taxYear, String taxConsultant) {
        this.name = name;
        this.age = age;
        this.year = year;
        this.occupation = occupation;
        this.taxYear = taxYear;
        this.taxConsultant = taxConsultant;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public String getOccupation() {
        return occupation;
    }

    public void setOccupation(String occupation) {
        this.occupation = occupation;
    }

    public int getTaxYear() {
        return taxYear;
    }

    public void setTaxYear(int taxYear) {
        this.taxYear = taxYear;
    }

    public String getTaxConsultant() {
        return taxConsultant;
    }

    public void setTaxConsultant(String taxConsultant) {
        this.taxConsultant = taxConsultant;
    }

    @Override
    public String toString() {
        return "ClientData{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", year=" + year +
                ", occupation='" + occupation + '\'' +
                ", taxYear=" + taxYear +
                ", taxConsultant='" + taxConsultant + '\'' +
                '}';
    }
}

public static class Client {

    @Reindex(name = "id", isPrimaryKey = true)
    private int id;

    @Reindex(name = "client_data")
    private ClientData data;

    // You can add more fields here if necessary as indicated by the "..." in your
    // Go struct

    public Client() {
    }

    // All-args constructor
    public Client(int id, ClientData data) {
        this.id = id;
        this.data = data;
    }

    // Getters and Setters
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public ClientData getData() {
        return data;
    }

    public void setData(ClientData data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Client{" +
                "id=" + id +
                ", data=" + data +
                '}';
    }
}

// ...

ClientData clientData = new ClientData();
clientData.setField(field);
// ...
clientData.setField1(field1);

db.query("clients", Client.class)
    .where("id", Condition.EQ, 100)
    .set("client_data", clientData)
    .update();

UPDATE-запросы для удаления полей записей

В Reindexer используется следующий синтаксис UPDATE-запросов для удаления полей:

UPDATE nsName
DROP field1, field2, ..
WHERE condition;

С помощью таких запросов можно удалить только неиндексные поля или индексные sparse-поля.

Примеры:

db.Query("items").Where("id", reindexer.EQ, 1).Drop("fieldToDrop1").Drop("fieldToDrop2").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .drop("fieldToDrop1")
        .drop("fieldToDrop2")
        .update()
)
db.query("items", Item.class)
    .where("id", Condition.EQ, 1)
    .drop("fieldToDrop1")
    .drop("fieldToDrop2")
    .update();
UPDATE items DROP fieldToDrop1, fieldToDrop2 WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "drop_fields": [
    "fieldToDrop1",
    "fieldToDrop2"
  ]
}'

Удаление элемента массива по индексу

Примеры команд для удаления элемента массива:

db.Query("items").Where("id", reindexer.EQ, 1).Drop("arrayField[2]").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .drop("arrayField[2]")
        .update()
)
db.query("items", Item.class)
    .where("id", Condition.EQ, 1)
    .drop("fieldToDrop[2]")
    .update();
UPDATE items DROP arrayField[2] WHERE id = 11
curl --location --request PUT 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
    "namespace": "items",
    "filters": [
        {
            "Field": "id",
            "Cond": "EQ",
            "Value": [
                1
            ]
        }
    ],
    "drop_fields" : [
        "arrayField[2]"
    ]
}'

Удаление элементов массива по значению

Для удаления элементов массива по значению используются функции:

  • array_remove(). Удаляет из массива все найденные вхождения элементов, переданных в качестве аргументов;
  • array_remove_once(). Удаляет из массива только первые найденные вхождения элементов, переданных в качестве аргументов. Удаление происходит по числу вхождений: если какое-то значение задано несколько раз, то и из целевого массива будет удалено столько же его копий.

Функции могут принимать в качестве аргумента одно или несколько значений. В обоих случаях значения указываются в квадратных скобках.

Пример удаления всех найденных вхождений элементов, переданных в качестве аргументов, с помощью array_remove:

В Go array_remove используется через метод SetExpression().

db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "array_remove(arrayField, [5,6,7,8])").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "array_remove(arrayField, [5,6,7,8])")
        .update()
)
UPDATE items SET arrayField = array_remove(arrayField, [5,6,7,8]) WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "array_remove(arrayField, [5,6,7,8])"
      ]
    }
  ]
}'

Пример удаления из массива только первых найденных вхождений элементов, переданных в качестве аргументов, помощью array_remove_once:

В Go array_remove_once используется через метод SetExpression().

db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "array_remove_once(arrayField, [5,5,5,6])").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "array_remove_once(arrayField, [5,5,5,6])")
        .update()
)
UPDATE items SET arrayField = array_remove_once(arrayField, [5,5,5,6]) WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "array_remove_once(arrayField, [5,5,5,6])"
      ]
    }
  ]
}'

Использование array_remove и array_remove_once можно комбинировать с добавлением элементов в начало или конец массива:

db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "array_remove(arrayField, [5,6,7,8]) || [1,2,3]").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "array_remove(arrayField, [5,6,7,8]) || [1,2,3]")
        .update()
)
UPDATE items SET arrayField = array_remove(arrayField, [5,6,7,8]) || [1,2,3] WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "array_remove(arrayField, [5,6,7,8]) || [1,2,3]"
      ]
    }
  ]
}'

В качестве второго параметра в array_remove и array_remove_once может быть использован не только набор значений, но и имя поля, содержащего массив:

db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "array_remove(arrayField, arrayField2)").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "array_remove(arrayField, arrayField2)")
        .update()
)
UPDATE items SET arrayField = array_remove(arrayField, arrayField2) WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "array_remove(arrayField, arrayField2)"
      ]
    }
  ]
}'

Указание набора значений или имени поля, содержащего массив, в качестве набора значений для удаления из другого можно комбинировать с добавлением элементов в начало или конец массива:

db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "[3] || array_remove(arrayField, arrayField2) || arrayField3 || array_remove(arrayField, [8,1]) || [2,4]").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "[3] || array_remove(arrayField, arrayField2) || arrayField3 || array_remove(arrayField, [8,1]) || [2,4]")
        .update()
)
UPDATE items SET arrayField = [3] || array_remove(arrayField, arrayField2) || arrayField3 || array_remove(arrayField, [8,1]) || [2,4] WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "[3] || array_remove(arrayField, arrayField2) || arrayField3 || array_remove(arrayField, [8,1]) || [2,4]"
      ]
    }
  ]
}'

array_remove и array_remove_once можно использовать для инициализации массива отфильтрованными значениями из другого поля:

db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "array_remove(arrayField2, arrayField3)").Update()
db.Query("items").Where("id", reindexer.EQ, 1).SetExpression("arrayField", "array_remove([1,2,3], arrayField2)").Update()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "array_remove(arrayField2, arrayField3)")
        .update()
)
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .expression("arrayField", "array_remove([1,2,3], arrayField2)")
        .update()
)
UPDATE items SET arrayField = array_remove(arrayField2, arrayField3) WHERE id = 1
UPDATE items SET arrayField = array_remove([1,2,3], arrayField2) WHERE id = 1
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "array_remove(arrayField2, arrayField3)"
      ]
    }
  ]
}'
curl --location --request PUT 'http://127.0.0.1:9098/api/v1/db/mydb/query' \
--header 'Content-Type: application/json' \
--data '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ],
  "update_fields": [
    {
      "name": "arrayField",
      "type": "expression",
      "is_array": false,
      "values": [
        "array_remove([1,2,3], arrayField2)"
      ]
    }
  ]
}'

DELETE-запросы

DELETE-запросы в Reindexer используются для удаления одной или нескольких записей из неймспейса. Пример:

db.Query("items").Where("id", reindexer.EQ, 11).Delete()
(
    db.new_query("items")
        .where("id", CondType.CondEq, 1)
        .delete()
)
db.query("items", Item.class)
    .where("id", Condition.EQ, 11)
    .delete();
DELETE FROM items WHERE id = 11
curl --location --request DELETE 'http://127.0.0.1:9088/api/v1/db/testdb/query' \
--header 'Content-Type: application/json' \
--data-raw '{
  "namespace": "items",
  "filters": [
    {
      "Field": "id",
      "Cond": "EQ",
      "Value": [
        1
      ]
    }
  ]
}'